nss: upgrade to release 3.73
[LibreOffice.git] / sal / rtl / strtmpl.cxx
blob082dcd7d3913a1ceeb20a2cfa190370dc2842c97
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 for (;;)
106 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE(*pStr1)) -
107 static_cast<sal_Int32>(IMPL_RTL_USTRCODE(*pStr2));
108 if (!(nRet == 0 && *pStr2 ))
109 break;
110 pStr1++;
111 pStr2++;
114 return nRet;
116 #endif
119 /* ----------------------------------------------------------------------- */
121 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
122 sal_Int32 nStr1Len,
123 const IMPL_RTL_STRCODE* pStr2,
124 sal_Int32 nStr2Len )
125 SAL_THROW_EXTERN_C()
127 assert(nStr1Len >= 0);
128 assert(nStr2Len >= 0);
129 #if !IMPL_RTL_IS_USTRING
130 // take advantage of builtin optimisations
131 sal_Int32 nMin = std::min(nStr1Len, nStr2Len);
132 sal_Int32 nRet = memcmp(pStr1, pStr2, nMin);
133 return nRet == 0 ? nStr1Len - nStr2Len : nRet;
134 #else
135 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
137 // take advantage of builtin optimisations
138 sal_Int32 nMin = std::min(nStr1Len, nStr2Len);
139 sal_Int32 nRet = wmemcmp(reinterpret_cast<wchar_t const *>(pStr1),
140 reinterpret_cast<wchar_t const *>(pStr2), nMin);
141 return nRet == 0 ? nStr1Len - nStr2Len : nRet;
143 else
145 sal_Int32 nRet = nStr1Len - nStr2Len;
146 int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
148 while( --nCount >= 0 ) {
149 if (*pStr1 != *pStr2) {
150 break;
152 ++pStr1;
153 ++pStr2;
156 if( nCount >= 0 )
157 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1 ))
158 - static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2 ));
160 return nRet;
162 #endif
165 /* ----------------------------------------------------------------------- */
167 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
168 sal_Int32 nStr1Len,
169 const IMPL_RTL_STRCODE* pStr2,
170 sal_Int32 nStr2Len,
171 sal_Int32 nShortenedLength )
172 SAL_THROW_EXTERN_C()
174 assert(nStr1Len >= 0);
175 assert(nStr2Len >= 0);
176 assert(nShortenedLength >= 0);
177 #if !IMPL_RTL_IS_USTRING
178 // take advantage of builtin optimisations
179 sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
180 sal_Int32 nRet = memcmp(pStr1, pStr2, nMin);
181 if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
182 return nStr1Len - nStr2Len;
183 return nRet;
184 #else
185 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
187 // take advantage of builtin optimisations
188 sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
189 sal_Int32 nRet = wmemcmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2), nMin);
190 if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
191 return nStr1Len - nStr2Len;
192 return nRet;
194 else
196 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
197 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
198 sal_Int32 nRet;
199 while ( (nShortenedLength > 0) &&
200 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
202 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1 ))-
203 static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2 ));
204 if ( nRet )
205 return nRet;
207 nShortenedLength--;
208 pStr1++;
209 pStr2++;
212 if ( nShortenedLength <= 0 )
213 return 0;
214 return nStr1Len - nStr2Len;
216 #endif
219 /* ----------------------------------------------------------------------- */
221 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
222 sal_Int32 nStr1Len,
223 const IMPL_RTL_STRCODE* pStr2,
224 sal_Int32 nStr2Len )
225 SAL_THROW_EXTERN_C()
227 assert(nStr1Len >= 0);
228 assert(nStr2Len >= 0);
229 const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
230 const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
231 sal_Int32 nRet;
232 while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
234 pStr1Run--;
235 pStr2Run--;
236 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1Run ))-
237 static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2Run ));
238 if ( nRet )
239 return nRet;
242 return nStr1Len - nStr2Len;
245 /* ----------------------------------------------------------------------- */
247 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
248 const IMPL_RTL_STRCODE* pStr2 )
249 SAL_THROW_EXTERN_C()
251 assert(pStr1);
252 assert(pStr2);
253 sal_uInt32 c1;
256 c1 = IMPL_RTL_USTRCODE(*pStr1);
257 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
258 c1, IMPL_RTL_USTRCODE(*pStr2));
259 if ( nRet != 0 )
260 return nRet;
262 pStr1++;
263 pStr2++;
265 while (c1);
267 return 0;
270 /* ----------------------------------------------------------------------- */
272 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
273 sal_Int32 nStr1Len,
274 const IMPL_RTL_STRCODE* pStr2,
275 sal_Int32 nStr2Len )
276 SAL_THROW_EXTERN_C()
278 assert(nStr1Len >= 0);
279 assert(nStr2Len >= 0);
280 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
281 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
282 while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
284 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
285 IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
286 if ( nRet != 0 )
287 return nRet;
289 pStr1++;
290 pStr2++;
293 return nStr1Len - nStr2Len;
296 /* ----------------------------------------------------------------------- */
298 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
299 sal_Int32 nStr1Len,
300 const IMPL_RTL_STRCODE* pStr2,
301 sal_Int32 nStr2Len,
302 sal_Int32 nShortenedLength )
303 SAL_THROW_EXTERN_C()
305 assert(nStr1Len >= 0);
306 assert(nStr2Len >= 0);
307 assert(nShortenedLength >= 0);
308 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
309 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
310 while ( (nShortenedLength > 0) &&
311 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
313 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
314 IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
315 if ( nRet != 0 )
316 return nRet;
318 nShortenedLength--;
319 pStr1++;
320 pStr2++;
323 if ( nShortenedLength <= 0 )
324 return 0;
325 return nStr1Len - nStr2Len;
328 /* ----------------------------------------------------------------------- */
330 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
331 SAL_THROW_EXTERN_C()
333 return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
336 /* ----------------------------------------------------------------------- */
338 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
339 sal_Int32 nLen )
340 SAL_THROW_EXTERN_C()
342 assert(nLen >= 0);
343 sal_uInt32 h = static_cast<sal_uInt32>(nLen);
344 while ( nLen > 0 )
346 h = (h*37U) + IMPL_RTL_USTRCODE( *pStr );
347 pStr++;
348 nLen--;
350 return static_cast<sal_Int32>(h);
353 /* ----------------------------------------------------------------------- */
355 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
356 IMPL_RTL_STRCODE c )
357 SAL_THROW_EXTERN_C()
359 assert(pStr);
360 #if !IMPL_RTL_IS_USTRING
361 // take advantage of builtin optimisations
362 const IMPL_RTL_STRCODE* p = strchr(pStr, c);
363 return p ? p - pStr : -1;
364 #else
365 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
367 // take advantage of builtin optimisations
368 wchar_t const * p = wcschr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c));
369 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
371 else
373 const IMPL_RTL_STRCODE* pTempStr = pStr;
374 while ( *pTempStr )
376 if ( *pTempStr == c )
377 return pTempStr-pStr;
379 pTempStr++;
382 return -1;
384 #endif
387 /* ----------------------------------------------------------------------- */
389 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
390 sal_Int32 nLen,
391 IMPL_RTL_STRCODE c )
392 SAL_THROW_EXTERN_C()
394 // assert(nLen >= 0);
395 #if !IMPL_RTL_IS_USTRING
396 // take advantage of builtin optimisations
397 IMPL_RTL_STRCODE* p = static_cast<IMPL_RTL_STRCODE*>(std::memchr(const_cast<IMPL_RTL_STRCODE *>(pStr), c, nLen));
398 return p ? p - pStr : -1;
399 #else
400 const IMPL_RTL_STRCODE* pTempStr = pStr;
401 while ( nLen > 0 )
403 if ( *pTempStr == c )
404 return pTempStr-pStr;
406 pTempStr++;
407 nLen--;
410 return -1;
411 #endif
414 /* ----------------------------------------------------------------------- */
416 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
417 IMPL_RTL_STRCODE c )
418 SAL_THROW_EXTERN_C()
420 assert(pStr);
421 #if !IMPL_RTL_IS_USTRING
422 // take advantage of builtin optimisations
423 const IMPL_RTL_STRCODE* p = strrchr(pStr, c);
424 return p ? p - pStr : -1;
425 #else
426 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
428 // take advantage of builtin optimisations
429 wchar_t const * p = wcsrchr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c));
430 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
432 else
434 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
436 #endif
439 /* ----------------------------------------------------------------------- */
441 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
442 sal_Int32 nLen,
443 IMPL_RTL_STRCODE c )
444 SAL_THROW_EXTERN_C()
446 assert(nLen >= 0);
447 pStr += nLen;
448 while ( nLen > 0 )
450 nLen--;
451 pStr--;
453 if ( *pStr == c )
454 return nLen;
457 return -1;
460 /* ----------------------------------------------------------------------- */
462 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
463 const IMPL_RTL_STRCODE* pSubStr )
464 SAL_THROW_EXTERN_C()
466 assert(pStr);
467 assert(pSubStr);
468 #if !IMPL_RTL_IS_USTRING
469 // take advantage of builtin optimisations
470 const IMPL_RTL_STRCODE* p = strstr(pStr, pSubStr);
471 return p ? p - pStr : -1;
472 #else
473 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
475 // take advantage of builtin optimisations
476 wchar_t const * p = wcsstr(reinterpret_cast<wchar_t const *>(pStr), reinterpret_cast<wchar_t const *>(pSubStr));
477 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
479 else
481 return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
482 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
484 #endif
487 /* ----------------------------------------------------------------------- */
489 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
490 sal_Int32 nStrLen,
491 const IMPL_RTL_STRCODE* pSubStr,
492 sal_Int32 nSubLen )
493 SAL_THROW_EXTERN_C()
495 assert(nStrLen >= 0);
496 assert(nSubLen >= 0);
497 /* faster search for a single character */
498 if ( nSubLen < 2 )
500 /* an empty SubString is always not findable */
501 if ( nSubLen == 1 )
503 IMPL_RTL_STRCODE c = *pSubStr;
504 const IMPL_RTL_STRCODE* pTempStr = pStr;
505 while ( nStrLen > 0 )
507 if ( *pTempStr == c )
508 return pTempStr-pStr;
510 pTempStr++;
511 nStrLen--;
515 else
517 const IMPL_RTL_STRCODE* pTempStr = pStr;
518 while ( nStrLen > 0 )
520 if ( *pTempStr == *pSubStr )
522 /* Compare SubString */
523 if ( nSubLen <= nStrLen )
525 const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
526 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
527 sal_Int32 nTempLen = nSubLen;
528 while ( nTempLen )
530 if ( *pTempStr1 != *pTempStr2 )
531 break;
533 pTempStr1++;
534 pTempStr2++;
535 nTempLen--;
538 if ( !nTempLen )
539 return pTempStr-pStr;
541 else
542 break;
545 nStrLen--;
546 pTempStr++;
550 return -1;
553 /* ----------------------------------------------------------------------- */
555 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
556 const IMPL_RTL_STRCODE* pSubStr )
557 SAL_THROW_EXTERN_C()
559 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
560 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
563 /* ----------------------------------------------------------------------- */
565 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
566 sal_Int32 nStrLen,
567 const IMPL_RTL_STRCODE* pSubStr,
568 sal_Int32 nSubLen )
569 SAL_THROW_EXTERN_C()
571 assert(nStrLen >= 0);
572 assert(nSubLen >= 0);
573 /* faster search for a single character */
574 if ( nSubLen < 2 )
576 /* an empty SubString is always not findable */
577 if ( nSubLen == 1 )
579 IMPL_RTL_STRCODE c = *pSubStr;
580 pStr += nStrLen;
581 while ( nStrLen > 0 )
583 nStrLen--;
584 pStr--;
586 if ( *pStr == c )
587 return nStrLen;
591 else
593 pStr += nStrLen;
594 nStrLen -= nSubLen;
595 pStr -= nSubLen;
596 while ( nStrLen >= 0 )
598 const IMPL_RTL_STRCODE* pTempStr1 = pStr;
599 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
600 sal_Int32 nTempLen = nSubLen;
601 while ( nTempLen )
603 if ( *pTempStr1 != *pTempStr2 )
604 break;
606 pTempStr1++;
607 pTempStr2++;
608 nTempLen--;
611 if ( !nTempLen )
612 return nStrLen;
614 nStrLen--;
615 pStr--;
619 return -1;
622 /* ----------------------------------------------------------------------- */
624 void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
625 IMPL_RTL_STRCODE cOld,
626 IMPL_RTL_STRCODE cNew )
627 SAL_THROW_EXTERN_C()
629 assert(pStr);
630 while ( *pStr )
632 if ( *pStr == cOld )
633 *pStr = cNew;
635 pStr++;
639 /* ----------------------------------------------------------------------- */
641 void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
642 sal_Int32 nLen,
643 IMPL_RTL_STRCODE cOld,
644 IMPL_RTL_STRCODE cNew )
645 SAL_THROW_EXTERN_C()
647 assert(nLen >= 0);
648 while ( nLen > 0 )
650 if ( *pStr == cOld )
651 *pStr = cNew;
653 pStr++;
654 nLen--;
658 /* ----------------------------------------------------------------------- */
660 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
661 SAL_THROW_EXTERN_C()
663 assert(pStr);
664 while ( *pStr )
666 *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
668 pStr++;
672 /* ----------------------------------------------------------------------- */
674 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
675 sal_Int32 nLen )
676 SAL_THROW_EXTERN_C()
678 assert(nLen >= 0);
679 while ( nLen > 0 )
681 *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
683 pStr++;
684 nLen--;
688 /* ----------------------------------------------------------------------- */
690 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
691 SAL_THROW_EXTERN_C()
693 assert(pStr);
694 while ( *pStr )
696 *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
698 pStr++;
702 /* ----------------------------------------------------------------------- */
704 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
705 sal_Int32 nLen )
706 SAL_THROW_EXTERN_C()
708 assert(nLen >= 0);
709 while ( nLen > 0 )
711 *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
713 pStr++;
714 nLen--;
718 /* ----------------------------------------------------------------------- */
720 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
721 SAL_THROW_EXTERN_C()
723 return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
726 /* ----------------------------------------------------------------------- */
728 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
729 SAL_THROW_EXTERN_C()
731 assert(nLen >= 0);
732 sal_Int32 nPreSpaces = 0;
733 sal_Int32 nPostSpaces = 0;
734 sal_Int32 nIndex = nLen-1;
736 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
737 nPreSpaces++;
739 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
741 nPostSpaces++;
742 nIndex--;
745 if ( nPostSpaces )
747 nLen -= nPostSpaces;
748 *(pStr+nLen) = 0;
751 if ( nPreSpaces )
753 nLen -= nPreSpaces;
754 memmove(pStr, pStr + nPreSpaces, nLen * sizeof(IMPL_RTL_STRCODE));
755 pStr += nLen;
756 *pStr = 0;
759 return nLen;
762 /* ----------------------------------------------------------------------- */
764 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
765 SAL_THROW_EXTERN_C()
767 assert(pStr);
768 if ( b )
770 *pStr = 't';
771 pStr++;
772 *pStr = 'r';
773 pStr++;
774 *pStr = 'u';
775 pStr++;
776 *pStr = 'e';
777 pStr++;
778 *pStr = 0;
779 return 4;
781 else
783 *pStr = 'f';
784 pStr++;
785 *pStr = 'a';
786 pStr++;
787 *pStr = 'l';
788 pStr++;
789 *pStr = 's';
790 pStr++;
791 *pStr = 'e';
792 pStr++;
793 *pStr = 0;
794 return 5;
798 /* ----------------------------------------------------------------------- */
800 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
801 IMPL_RTL_STRCODE c )
802 SAL_THROW_EXTERN_C()
804 assert(pStr);
805 *pStr++ = c;
806 *pStr = 0;
807 return 1;
810 /* ----------------------------------------------------------------------- */
812 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
813 sal_Int32 n,
814 sal_Int16 nRadix )
815 SAL_THROW_EXTERN_C()
817 assert(pStr);
818 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
819 char aBuf[RTL_STR_MAX_VALUEOFINT32];
820 char* pBuf = aBuf;
821 sal_Int32 nLen = 0;
822 sal_uInt32 nValue;
824 /* Radix must be valid */
825 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
826 nRadix = 10;
828 /* is value negative */
829 if ( n < 0 )
831 *pStr = '-';
832 pStr++;
833 nLen++;
834 nValue = n == SAL_MIN_INT32 ? static_cast<sal_uInt32>(n) : -n;
836 else
837 nValue = n;
839 /* create a recursive buffer with all values, except the last one */
842 char nDigit = static_cast<char>(nValue % nRadix);
843 nValue /= nRadix;
844 if ( nDigit > 9 )
845 *pBuf = (nDigit-10) + 'a';
846 else
847 *pBuf = (nDigit + '0' );
848 pBuf++;
850 while ( nValue > 0 );
852 /* copy the values in the right direction into the destination buffer */
855 pBuf--;
856 *pStr = *pBuf;
857 pStr++;
858 nLen++;
860 while ( pBuf != aBuf );
861 *pStr = 0;
863 return nLen;
866 /* ----------------------------------------------------------------------- */
868 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
869 sal_Int64 n,
870 sal_Int16 nRadix )
871 SAL_THROW_EXTERN_C()
873 assert(pStr);
874 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
875 char aBuf[RTL_STR_MAX_VALUEOFINT64];
876 char* pBuf = aBuf;
877 sal_Int32 nLen = 0;
878 sal_uInt64 nValue;
880 /* Radix must be valid */
881 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
882 nRadix = 10;
884 /* is value negative */
885 if ( n < 0 )
887 *pStr = '-';
888 pStr++;
889 nLen++;
890 nValue = n == SAL_MIN_INT64 ? static_cast<sal_uInt64>(n) : -n;
892 else
893 nValue = n;
895 /* create a recursive buffer with all values, except the last one */
898 char nDigit = static_cast<char>(nValue % nRadix);
899 nValue /= nRadix;
900 if ( nDigit > 9 )
901 *pBuf = (nDigit-10) + 'a';
902 else
903 *pBuf = (nDigit + '0' );
904 pBuf++;
906 while ( nValue > 0 );
908 /* copy the values in the right direction into the destination buffer */
911 pBuf--;
912 *pStr = *pBuf;
913 pStr++;
914 nLen++;
916 while ( pBuf != aBuf );
917 *pStr = 0;
919 return nLen;
922 /* ----------------------------------------------------------------------- */
924 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfUInt64 )( IMPL_RTL_STRCODE* pStr,
925 sal_uInt64 n,
926 sal_Int16 nRadix )
927 SAL_THROW_EXTERN_C()
929 assert(pStr);
930 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
931 char aBuf[RTL_STR_MAX_VALUEOFUINT64];
932 char* pBuf = aBuf;
933 sal_Int32 nLen = 0;
934 sal_uInt64 nValue;
936 /* Radix must be valid */
937 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
938 nRadix = 10;
940 nValue = n;
942 /* create a recursive buffer with all values, except the last one */
945 char nDigit = static_cast<char>(nValue % nRadix);
946 nValue /= nRadix;
947 if ( nDigit > 9 )
948 *pBuf = (nDigit-10) + 'a';
949 else
950 *pBuf = (nDigit + '0' );
951 pBuf++;
953 while ( nValue > 0 );
955 /* copy the values in the right direction into the destination buffer */
958 pBuf--;
959 *pStr = *pBuf;
960 pStr++;
961 nLen++;
963 while ( pBuf != aBuf );
964 *pStr = 0;
966 return nLen;
969 /* ----------------------------------------------------------------------- */
971 sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
972 SAL_THROW_EXTERN_C()
974 assert(pStr);
975 if ( *pStr == '1' )
976 return true;
978 if ( (*pStr == 'T') || (*pStr == 't') )
980 pStr++;
981 if ( (*pStr == 'R') || (*pStr == 'r') )
983 pStr++;
984 if ( (*pStr == 'U') || (*pStr == 'u') )
986 pStr++;
987 if ( (*pStr == 'E') || (*pStr == 'e') )
988 return true;
993 return false;
996 /* ----------------------------------------------------------------------- */
997 namespace {
998 template<typename T, typename U> T IMPL_RTL_STRNAME( toInt_WithLength )( const IMPL_RTL_STRCODE* pStr,
999 sal_Int16 nRadix,
1000 sal_Int32 nStrLength )
1002 static_assert(std::numeric_limits<T>::is_signed, "is signed");
1003 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
1004 assert( nStrLength >= 0 );
1005 bool bNeg;
1006 sal_Int16 nDigit;
1007 U n = 0;
1008 const IMPL_RTL_STRCODE* pEnd = pStr + nStrLength;
1010 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1011 nRadix = 10;
1013 /* Skip whitespaces */
1014 while ( pStr != pEnd && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1015 pStr++;
1017 if ( *pStr == '-' )
1019 bNeg = true;
1020 pStr++;
1022 else
1024 if ( *pStr == '+' )
1025 pStr++;
1026 bNeg = false;
1029 T nDiv;
1030 sal_Int16 nMod;
1031 if ( bNeg )
1033 nDiv = std::numeric_limits<T>::min() / nRadix;
1034 nMod = std::numeric_limits<T>::min() % nRadix;
1035 // Cater for C++03 implementations that round the quotient down
1036 // instead of truncating towards zero as mandated by C++11:
1037 if ( nMod > 0 )
1039 --nDiv;
1040 nMod -= nRadix;
1042 nDiv = -nDiv;
1043 nMod = -nMod;
1045 else
1047 nDiv = std::numeric_limits<T>::max() / nRadix;
1048 nMod = std::numeric_limits<T>::max() % nRadix;
1051 while ( pStr != pEnd )
1053 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1054 if ( nDigit < 0 )
1055 break;
1056 assert(nDiv > 0);
1057 if( static_cast<U>( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1058 return 0;
1060 n *= nRadix;
1061 n += nDigit;
1063 pStr++;
1066 if ( bNeg )
1067 return n == static_cast<U>(std::numeric_limits<T>::min())
1068 ? std::numeric_limits<T>::min() : -static_cast<T>(n);
1069 else
1070 return static_cast<T>(n);
1074 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
1075 sal_Int16 nRadix )
1076 SAL_THROW_EXTERN_C()
1078 assert(pStr);
1079 return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int32, sal_uInt32>(pStr, nRadix, IMPL_RTL_STRNAME( getLength )(pStr));
1082 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
1083 sal_Int16 nRadix )
1084 SAL_THROW_EXTERN_C()
1086 assert(pStr);
1087 return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int64, sal_uInt64>(pStr, nRadix, IMPL_RTL_STRNAME( getLength )(pStr));
1090 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64_WithLength )( const IMPL_RTL_STRCODE* pStr,
1091 sal_Int16 nRadix,
1092 sal_Int32 nStrLength)
1093 SAL_THROW_EXTERN_C()
1095 assert(pStr);
1096 return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int64, sal_uInt64>(pStr, nRadix, nStrLength);
1099 /* ----------------------------------------------------------------------- */
1100 namespace {
1101 template <typename T> T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr,
1102 sal_Int16 nRadix )
1104 static_assert(!std::numeric_limits<T>::is_signed, "is not signed");
1105 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
1106 sal_Int16 nDigit;
1107 T n = 0;
1109 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1110 nRadix = 10;
1112 /* Skip whitespaces */
1113 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1114 ++pStr;
1116 // skip optional explicit sign
1117 if ( *pStr == '+' )
1118 ++pStr;
1120 T nDiv = std::numeric_limits<T>::max() / nRadix;
1121 sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix;
1122 while ( *pStr )
1124 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1125 if ( nDigit < 0 )
1126 break;
1127 if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1128 return 0;
1130 n *= nRadix;
1131 n += nDigit;
1133 ++pStr;
1136 return n;
1140 sal_uInt32 SAL_CALL IMPL_RTL_STRNAME( toUInt32 )( const IMPL_RTL_STRCODE* pStr,
1141 sal_Int16 nRadix )
1142 SAL_THROW_EXTERN_C()
1144 assert(pStr);
1145 return IMPL_RTL_STRNAME( toUInt )<sal_uInt32>(pStr, nRadix);
1148 sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr,
1149 sal_Int16 nRadix )
1150 SAL_THROW_EXTERN_C()
1152 assert(pStr);
1153 return IMPL_RTL_STRNAME( toUInt )<sal_uInt64>(pStr, nRadix);
1156 /* ======================================================================= */
1157 /* Internal String-Class help functions */
1158 /* ======================================================================= */
1160 IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
1162 IMPL_RTL_STRINGDATA * pData
1163 = (sal::static_int_cast< sal_uInt32 >(nLen)
1164 <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
1165 / sizeof (IMPL_RTL_STRCODE)))
1166 ? static_cast<IMPL_RTL_STRINGDATA *>(rtl_allocateString(
1167 sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)))
1168 : nullptr;
1169 if (pData != nullptr) {
1170 pData->refCount = 1;
1171 pData->length = nLen;
1172 pData->buffer[nLen] = 0;
1174 return pData;
1177 /* ----------------------------------------------------------------------- */
1179 static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
1180 IMPL_RTL_STRINGDATA* pStr,
1181 sal_Int32 nCount )
1183 assert(nCount >= 0);
1184 IMPL_RTL_STRCODE* pDest;
1185 const IMPL_RTL_STRCODE* pSrc;
1186 IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1187 OSL_ASSERT(pData != nullptr);
1189 pDest = pData->buffer;
1190 pSrc = pStr->buffer;
1192 memcpy( pDest, pSrc, nCount * sizeof(IMPL_RTL_STRCODE));
1194 *ppThis = pData;
1196 RTL_LOG_STRING_NEW( pData );
1197 return pDest + nCount;
1200 /* ======================================================================= */
1201 /* String-Class functions */
1202 /* ======================================================================= */
1204 namespace {
1206 void IMPL_RTL_ACQUIRE(IMPL_RTL_STRINGDATA * pThis)
1208 if (!SAL_STRING_IS_STATIC (pThis))
1209 osl_atomic_increment( &((pThis)->refCount) );
1214 /* ----------------------------------------------------------------------- */
1216 void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
1217 SAL_THROW_EXTERN_C()
1219 IMPL_RTL_ACQUIRE( pThis );
1222 /* ----------------------------------------------------------------------- */
1224 void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
1225 SAL_THROW_EXTERN_C()
1227 if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis)))
1228 return;
1230 /* OString doesn't have an 'intern' */
1231 #if IMPL_RTL_IS_USTRING
1232 if (SAL_STRING_IS_INTERN (pThis))
1234 internRelease (pThis);
1235 return;
1237 #endif
1239 if ( !osl_atomic_decrement( &(pThis->refCount) ) )
1241 RTL_LOG_STRING_DELETE( pThis );
1242 rtl_freeString( pThis );
1246 /* ----------------------------------------------------------------------- */
1248 void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
1249 SAL_THROW_EXTERN_C()
1251 assert(ppThis);
1252 if ( *ppThis)
1253 IMPL_RTL_STRINGNAME( release )( *ppThis );
1255 *ppThis = const_cast<IMPL_RTL_STRINGDATA*>(&IMPL_RTL_EMPTYSTRING);
1258 /* ----------------------------------------------------------------------- */
1260 IMPL_RTL_STRINGDATA* SAL_CALL IMPL_RTL_STRINGNAME( alloc )( sal_Int32 nLen )
1261 SAL_THROW_EXTERN_C()
1263 assert(nLen >= 0);
1264 return IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1267 /* ----------------------------------------------------------------------- */
1269 void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
1270 SAL_THROW_EXTERN_C()
1272 assert(ppThis);
1273 assert(nLen >= 0);
1274 if ( nLen <= 0 )
1275 IMPL_RTL_STRINGNAME( new )( ppThis );
1276 else
1278 if ( *ppThis)
1279 IMPL_RTL_STRINGNAME( release )( *ppThis );
1281 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1282 OSL_ASSERT(*ppThis != nullptr);
1283 (*ppThis)->length = 0;
1285 IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
1286 memset(pTempStr, 0, nLen*sizeof(IMPL_RTL_STRCODE));
1290 /* ----------------------------------------------------------------------- */
1292 void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
1293 const IMPL_RTL_STRINGDATA* pStr )
1294 SAL_THROW_EXTERN_C()
1296 assert(ppThis);
1297 assert(pStr);
1298 IMPL_RTL_STRINGDATA* pOrg;
1300 if ( !pStr->length )
1302 IMPL_RTL_STRINGNAME( new )( ppThis );
1303 return;
1306 pOrg = *ppThis;
1307 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1308 OSL_ASSERT(*ppThis != nullptr);
1309 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
1310 RTL_LOG_STRING_NEW( *ppThis );
1312 /* must be done last, if pStr == *ppThis */
1313 if ( pOrg )
1314 IMPL_RTL_STRINGNAME( release )( pOrg );
1317 /* ----------------------------------------------------------------------- */
1319 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
1320 const IMPL_RTL_STRCODE* pCharStr )
1321 SAL_THROW_EXTERN_C()
1323 assert(ppThis);
1324 IMPL_RTL_STRINGDATA* pOrg;
1325 sal_Int32 nLen;
1327 if ( pCharStr )
1329 nLen = IMPL_RTL_STRNAME( getLength )( pCharStr );
1331 else
1332 nLen = 0;
1334 if ( !nLen )
1336 IMPL_RTL_STRINGNAME( new )( ppThis );
1337 return;
1340 pOrg = *ppThis;
1341 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1342 OSL_ASSERT(*ppThis != nullptr);
1343 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1344 RTL_LOG_STRING_NEW( *ppThis );
1346 /* must be done last, if pCharStr == *ppThis */
1347 if ( pOrg )
1348 IMPL_RTL_STRINGNAME( release )( pOrg );
1351 /* ----------------------------------------------------------------------- */
1353 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
1354 const IMPL_RTL_STRCODE* pCharStr,
1355 sal_Int32 nLen )
1356 SAL_THROW_EXTERN_C()
1358 assert(ppThis);
1359 assert(nLen >= 0);
1360 IMPL_RTL_STRINGDATA* pOrg;
1362 if ( !pCharStr || (nLen <= 0) )
1364 IMPL_RTL_STRINGNAME( new )( ppThis );
1365 return;
1368 pOrg = *ppThis;
1369 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1370 OSL_ASSERT(*ppThis != nullptr);
1371 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1373 RTL_LOG_STRING_NEW( *ppThis );
1375 /* must be done last, if pCharStr == *ppThis */
1376 if ( pOrg )
1377 IMPL_RTL_STRINGNAME( release )( pOrg );
1380 /* ----------------------------------------------------------------------- */
1382 void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis,
1383 const IMPL_RTL_STRINGDATA* pFrom,
1384 sal_Int32 beginIndex,
1385 sal_Int32 count )
1386 SAL_THROW_EXTERN_C()
1388 assert(ppThis);
1389 if ( beginIndex == 0 && count == pFrom->length )
1391 IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) );
1392 return;
1394 if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length )
1396 assert(false); // fail fast at least in debug builds
1397 IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 );
1398 return;
1401 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count );
1404 /* ----------------------------------------------------------------------- */
1406 // Used when creating from string literals.
1407 void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis,
1408 const char* pCharStr,
1409 sal_Int32 nLen,
1410 sal_Int32 allocExtra )
1411 SAL_THROW_EXTERN_C()
1413 assert(ppThis);
1414 assert(nLen >= 0);
1415 assert(allocExtra >= 0);
1416 if ( nLen + allocExtra == 0 )
1418 IMPL_RTL_STRINGNAME( new )( ppThis );
1419 return;
1422 if ( *ppThis )
1423 IMPL_RTL_STRINGNAME( release )( *ppThis );
1425 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra );
1426 assert( *ppThis != nullptr );
1428 (*ppThis)->length = nLen; // fix after possible allocExtra != 0
1429 (*ppThis)->buffer[nLen] = 0;
1430 IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
1431 sal_Int32 nCount;
1432 for( nCount = nLen; nCount > 0; --nCount )
1434 #if IMPL_RTL_IS_USTRING
1435 assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
1436 #endif
1437 SAL_WARN_IF( (static_cast<unsigned char>(*pCharStr)) == '\0', "rtl.string",
1438 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1440 *pBuffer = *pCharStr;
1441 pBuffer++;
1442 pCharStr++;
1445 RTL_LOG_STRING_NEW( *ppThis );
1448 /* ----------------------------------------------------------------------- */
1450 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
1451 IMPL_RTL_STRINGDATA* pStr )
1452 SAL_THROW_EXTERN_C()
1454 assert(ppThis);
1455 /* must be done at first, if pStr == *ppThis */
1456 IMPL_RTL_ACQUIRE( pStr );
1458 if ( *ppThis )
1459 IMPL_RTL_STRINGNAME( release )( *ppThis );
1461 *ppThis = pStr;
1464 /* ----------------------------------------------------------------------- */
1466 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
1467 SAL_THROW_EXTERN_C()
1469 assert(pThis);
1470 return pThis->length;
1473 /* ----------------------------------------------------------------------- */
1475 IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
1476 SAL_THROW_EXTERN_C()
1478 assert(pThis);
1479 return pThis->buffer;
1482 /* ----------------------------------------------------------------------- */
1484 void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
1485 IMPL_RTL_STRINGDATA* pLeft,
1486 IMPL_RTL_STRINGDATA* pRight )
1487 SAL_THROW_EXTERN_C()
1489 assert(ppThis);
1490 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1492 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1493 if ( !pRight || !pRight->length )
1495 *ppThis = pLeft;
1496 IMPL_RTL_ACQUIRE( pLeft );
1498 else if ( !pLeft || !pLeft->length )
1500 *ppThis = pRight;
1501 IMPL_RTL_ACQUIRE( pRight );
1503 else if (pLeft->length
1504 > std::numeric_limits<sal_Int32>::max() - pRight->length)
1506 *ppThis = nullptr;
1508 else
1510 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
1511 OSL_ASSERT(pTempStr != nullptr);
1512 *ppThis = pTempStr;
1513 if (*ppThis != nullptr) {
1514 rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
1515 rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
1517 RTL_LOG_STRING_NEW( *ppThis );
1521 /* must be done last, if left or right == *ppThis */
1522 if ( pOrg )
1523 IMPL_RTL_STRINGNAME( release )( pOrg );
1526 /* ----------------------------------------------------------------------- */
1528 void SAL_CALL IMPL_RTL_STRINGNAME( ensureCapacity )( IMPL_RTL_STRINGDATA** ppThis,
1529 sal_Int32 size )
1530 SAL_THROW_EXTERN_C()
1532 assert(ppThis);
1533 IMPL_RTL_STRINGDATA* const pOrg = *ppThis;
1534 if ( pOrg->refCount == 1 && pOrg->length >= size )
1535 return;
1536 assert( pOrg->length <= size ); // do not truncate
1537 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( size );
1538 rtl_str_ImplCopy( pTempStr->buffer, pOrg->buffer, pOrg->length );
1539 // right now the length is still the same as of the original
1540 pTempStr->length = pOrg->length;
1541 pTempStr->buffer[ pOrg->length ] = '\0';
1542 *ppThis = pTempStr;
1543 RTL_LOG_STRING_NEW( *ppThis );
1545 IMPL_RTL_STRINGNAME( release )( pOrg );
1548 /* ----------------------------------------------------------------------- */
1550 void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
1551 IMPL_RTL_STRINGDATA* pStr,
1552 sal_Int32 nIndex,
1553 sal_Int32 nCount,
1554 IMPL_RTL_STRINGDATA* pNewSubStr )
1555 SAL_THROW_EXTERN_C()
1557 assert(ppThis);
1558 assert(nIndex >= 0 && nIndex <= pStr->length);
1559 assert(nCount >= 0);
1560 assert(nCount <= pStr->length - nIndex);
1561 /* Append? */
1562 if ( nIndex >= pStr->length )
1564 /* newConcat test, if pNewSubStr is 0 */
1565 IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
1566 return;
1569 /* negative index? */
1570 if ( nIndex < 0 )
1572 nCount -= nIndex;
1573 nIndex = 0;
1576 /* not more than the String length could be deleted */
1577 if ( nCount >= pStr->length-nIndex )
1579 nCount = pStr->length-nIndex;
1581 /* Assign of NewSubStr? */
1582 if ( !nIndex && (nCount >= pStr->length) )
1584 if ( !pNewSubStr )
1585 IMPL_RTL_STRINGNAME( new )( ppThis );
1586 else
1587 IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
1588 return;
1592 /* Assign of Str? */
1593 if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
1595 IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
1596 return;
1599 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1600 IMPL_RTL_STRCODE* pBuffer;
1601 sal_Int32 nNewLen;
1603 /* Calculate length of the new string */
1604 nNewLen = pStr->length-nCount;
1605 if ( pNewSubStr )
1606 nNewLen += pNewSubStr->length;
1608 /* Alloc New Buffer */
1609 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
1610 OSL_ASSERT(*ppThis != nullptr);
1611 pBuffer = (*ppThis)->buffer;
1612 if ( nIndex )
1614 rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
1615 pBuffer += nIndex;
1617 if ( pNewSubStr && pNewSubStr->length )
1619 rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
1620 pBuffer += pNewSubStr->length;
1622 rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
1624 RTL_LOG_STRING_NEW( *ppThis );
1625 /* must be done last, if pStr or pNewSubStr == *ppThis */
1626 if ( pOrg )
1627 IMPL_RTL_STRINGNAME( release )( pOrg );
1630 /* ----------------------------------------------------------------------- */
1632 void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
1633 IMPL_RTL_STRINGDATA* pStr,
1634 IMPL_RTL_STRCODE cOld,
1635 IMPL_RTL_STRCODE cNew )
1636 SAL_THROW_EXTERN_C()
1638 assert(ppThis);
1639 assert(pStr);
1640 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1641 bool bChanged = false;
1642 sal_Int32 nLen = pStr->length;
1643 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1645 while ( nLen > 0 )
1647 if ( *pCharStr == cOld )
1649 /* Copy String */
1650 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1652 /* replace/copy rest of the string */
1653 if ( pNewCharStr )
1655 *pNewCharStr = cNew;
1656 pNewCharStr++;
1657 pCharStr++;
1658 nLen--;
1660 while ( nLen > 0 )
1662 if ( *pCharStr == cOld )
1663 *pNewCharStr = cNew;
1664 else
1665 *pNewCharStr = *pCharStr;
1667 pNewCharStr++;
1668 pCharStr++;
1669 nLen--;
1673 bChanged = true;
1674 break;
1677 pCharStr++;
1678 nLen--;
1681 if ( !bChanged )
1683 *ppThis = pStr;
1684 IMPL_RTL_ACQUIRE( pStr );
1687 RTL_LOG_STRING_NEW( *ppThis );
1688 /* must be done last, if pStr == *ppThis */
1689 if ( pOrg )
1690 IMPL_RTL_STRINGNAME( release )( pOrg );
1693 /* ----------------------------------------------------------------------- */
1695 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
1696 IMPL_RTL_STRINGDATA* pStr )
1697 SAL_THROW_EXTERN_C()
1699 assert(ppThis);
1700 assert(pStr);
1701 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1702 bool bChanged = false;
1703 sal_Int32 nLen = pStr->length;
1704 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1706 while ( nLen > 0 )
1708 if ( rtl::isAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1710 /* Copy String */
1711 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1713 /* replace/copy rest of the string */
1714 if ( pNewCharStr )
1716 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1717 pNewCharStr++;
1718 pCharStr++;
1719 nLen--;
1721 while ( nLen > 0 )
1723 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1725 pNewCharStr++;
1726 pCharStr++;
1727 nLen--;
1731 bChanged = true;
1732 break;
1735 pCharStr++;
1736 nLen--;
1739 if ( !bChanged )
1741 *ppThis = pStr;
1742 IMPL_RTL_ACQUIRE( pStr );
1745 RTL_LOG_STRING_NEW( *ppThis );
1746 /* must be done last, if pStr == *ppThis */
1747 if ( pOrg )
1748 IMPL_RTL_STRINGNAME( release )( pOrg );
1751 /* ----------------------------------------------------------------------- */
1753 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
1754 IMPL_RTL_STRINGDATA* pStr )
1755 SAL_THROW_EXTERN_C()
1757 assert(ppThis);
1758 assert(pStr);
1759 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1760 bool bChanged = false;
1761 sal_Int32 nLen = pStr->length;
1762 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1764 while ( nLen > 0 )
1766 if ( rtl::isAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1768 /* Copy String */
1769 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1771 /* replace/copy rest of the string */
1772 if ( pNewCharStr )
1774 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1775 pNewCharStr++;
1776 pCharStr++;
1777 nLen--;
1779 while ( nLen > 0 )
1781 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1783 pNewCharStr++;
1784 pCharStr++;
1785 nLen--;
1789 bChanged = true;
1790 break;
1793 pCharStr++;
1794 nLen--;
1797 if ( !bChanged )
1799 *ppThis = pStr;
1800 IMPL_RTL_ACQUIRE( pStr );
1803 RTL_LOG_STRING_NEW( *ppThis );
1804 /* must be done last, if pStr == *ppThis */
1805 if ( pOrg )
1806 IMPL_RTL_STRINGNAME( release )( pOrg );
1809 /* ----------------------------------------------------------------------- */
1811 void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
1812 IMPL_RTL_STRINGDATA* pStr )
1813 SAL_THROW_EXTERN_C()
1815 assert(ppThis);
1816 assert(pStr);
1817 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1818 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1819 sal_Int32 nPreSpaces = 0;
1820 sal_Int32 nPostSpaces = 0;
1821 sal_Int32 nLen = pStr->length;
1822 sal_Int32 nIndex = nLen-1;
1824 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
1825 nPreSpaces++;
1827 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
1829 nPostSpaces++;
1830 nIndex--;
1833 if ( !nPreSpaces && !nPostSpaces )
1835 *ppThis = pStr;
1836 IMPL_RTL_ACQUIRE( pStr );
1838 else
1840 nLen -= nPostSpaces+nPreSpaces;
1841 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1842 assert(*ppThis);
1843 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
1846 RTL_LOG_STRING_NEW( *ppThis );
1847 /* must be done last, if pStr == *ppThis */
1848 if ( pOrg )
1849 IMPL_RTL_STRINGNAME( release )( pOrg );
1852 /* ----------------------------------------------------------------------- */
1854 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
1855 IMPL_RTL_STRINGDATA* pStr,
1856 sal_Int32 nToken,
1857 IMPL_RTL_STRCODE cTok,
1858 sal_Int32 nIndex )
1859 SAL_THROW_EXTERN_C()
1861 assert(ppThis);
1862 assert(pStr);
1863 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1864 const IMPL_RTL_STRCODE* pCharStrStart;
1865 const IMPL_RTL_STRCODE* pOrgCharStr;
1866 sal_Int32 nLen = pStr->length-nIndex;
1867 sal_Int32 nTokCount = 0;
1869 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1870 // negative:
1871 if (nIndex < 0)
1872 nToken = -1;
1874 pCharStr += nIndex;
1875 pOrgCharStr = pCharStr;
1876 pCharStrStart = pCharStr;
1877 while ( nLen > 0 )
1879 if ( *pCharStr == cTok )
1881 nTokCount++;
1883 if ( nTokCount == nToken )
1884 pCharStrStart = pCharStr+1;
1885 else
1887 if ( nTokCount > nToken )
1888 break;
1892 pCharStr++;
1893 nLen--;
1896 if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
1898 IMPL_RTL_STRINGNAME( new )( ppThis );
1899 if( (nToken < 0) || (nTokCount < nToken ) )
1900 return -1;
1901 else if( nLen > 0 )
1902 return nIndex+(pCharStr-pOrgCharStr)+1;
1903 else return -1;
1905 else
1907 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
1908 if ( nLen )
1909 return nIndex+(pCharStr-pOrgCharStr)+1;
1910 else
1911 return -1;
1915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */