update credits
[LibreOffice.git] / sal / rtl / strtmpl.cxx
blob1dba94baf6e3a72b5e460b1e53e4a9aea8b699b4
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 <string.h>
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 inline 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 = ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr1)))-
105 ((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 = strncmp(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 = wcsncmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2), nMin);
138 return nRet == 0 ? nStr1Len - nStr2Len : nRet;
140 else
142 sal_Int32 nRet = nStr1Len - nStr2Len;
143 int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
145 --pStr1;
146 --pStr2;
147 while( (--nCount >= 0) && (*++pStr1 == *++pStr2) ) ;
149 if( nCount >= 0 )
150 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))
151 - ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
153 return nRet;
155 #endif
158 /* ----------------------------------------------------------------------- */
160 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
161 sal_Int32 nStr1Len,
162 const IMPL_RTL_STRCODE* pStr2,
163 sal_Int32 nStr2Len,
164 sal_Int32 nShortenedLength )
165 SAL_THROW_EXTERN_C()
167 assert(nStr1Len >= 0);
168 assert(nStr2Len >= 0);
169 assert(nShortenedLength >= 0);
170 #if !IMPL_RTL_IS_USTRING
171 // take advantage of builtin optimisations
172 sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
173 sal_Int32 nRet = strncmp(pStr1, pStr2, nMin);
174 if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
175 return nStr1Len - nStr2Len;
176 return nRet;
177 #else
178 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
180 // take advantage of builtin optimisations
181 sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
182 sal_Int32 nRet = wcsncmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2), nMin);
183 if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
184 return nStr1Len - nStr2Len;
185 return nRet;
187 else
189 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
190 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
191 sal_Int32 nRet;
192 while ( (nShortenedLength > 0) &&
193 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
195 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))-
196 ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
197 if ( nRet )
198 return nRet;
200 nShortenedLength--;
201 pStr1++;
202 pStr2++;
205 if ( nShortenedLength <= 0 )
206 return 0;
207 return nStr1Len - nStr2Len;
209 #endif
212 /* ----------------------------------------------------------------------- */
214 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
215 sal_Int32 nStr1Len,
216 const IMPL_RTL_STRCODE* pStr2,
217 sal_Int32 nStr2Len )
218 SAL_THROW_EXTERN_C()
220 assert(nStr1Len >= 0);
221 assert(nStr2Len >= 0);
222 const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
223 const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
224 sal_Int32 nRet;
225 while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
227 pStr1Run--;
228 pStr2Run--;
229 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1Run )))-
230 ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2Run )));
231 if ( nRet )
232 return nRet;
235 return nStr1Len - nStr2Len;
238 /* ----------------------------------------------------------------------- */
240 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
241 const IMPL_RTL_STRCODE* pStr2 )
242 SAL_THROW_EXTERN_C()
244 assert(pStr1);
245 assert(pStr2);
246 sal_uInt32 c1;
249 c1 = IMPL_RTL_USTRCODE(*pStr1);
250 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
251 c1, IMPL_RTL_USTRCODE(*pStr2));
252 if ( nRet != 0 )
253 return nRet;
255 pStr1++;
256 pStr2++;
258 while (c1);
260 return 0;
263 /* ----------------------------------------------------------------------- */
265 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
266 sal_Int32 nStr1Len,
267 const IMPL_RTL_STRCODE* pStr2,
268 sal_Int32 nStr2Len )
269 SAL_THROW_EXTERN_C()
271 assert(nStr1Len >= 0);
272 assert(nStr2Len >= 0);
273 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
274 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
275 while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
277 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
278 IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
279 if ( nRet != 0 )
280 return nRet;
282 pStr1++;
283 pStr2++;
286 return nStr1Len - nStr2Len;
289 /* ----------------------------------------------------------------------- */
291 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
292 sal_Int32 nStr1Len,
293 const IMPL_RTL_STRCODE* pStr2,
294 sal_Int32 nStr2Len,
295 sal_Int32 nShortenedLength )
296 SAL_THROW_EXTERN_C()
298 assert(nStr1Len >= 0);
299 assert(nStr2Len >= 0);
300 assert(nShortenedLength >= 0);
301 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
302 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
303 while ( (nShortenedLength > 0) &&
304 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
306 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
307 IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
308 if ( nRet != 0 )
309 return nRet;
311 nShortenedLength--;
312 pStr1++;
313 pStr2++;
316 if ( nShortenedLength <= 0 )
317 return 0;
318 return nStr1Len - nStr2Len;
321 /* ----------------------------------------------------------------------- */
323 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
324 SAL_THROW_EXTERN_C()
326 return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
329 /* ----------------------------------------------------------------------- */
331 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
332 sal_Int32 nLen )
333 SAL_THROW_EXTERN_C()
335 assert(nLen >= 0);
336 sal_uInt32 h = static_cast<sal_uInt32>(nLen);
337 while ( nLen > 0 )
339 h = (h*37U) + IMPL_RTL_USTRCODE( *pStr );
340 pStr++;
341 nLen--;
343 return static_cast<sal_Int32>(h);
346 /* ----------------------------------------------------------------------- */
348 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
349 IMPL_RTL_STRCODE c )
350 SAL_THROW_EXTERN_C()
352 assert(pStr);
353 #if !IMPL_RTL_IS_USTRING
354 // take advantage of builtin optimisations
355 const IMPL_RTL_STRCODE* p = strchr(pStr, c);
356 return p ? p - pStr : -1;
357 #else
358 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
360 // take advantage of builtin optimisations
361 wchar_t const * p = wcschr(reinterpret_cast<wchar_t const *>(pStr), (wchar_t)c);
362 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
364 else
366 const IMPL_RTL_STRCODE* pTempStr = pStr;
367 while ( *pTempStr )
369 if ( *pTempStr == c )
370 return pTempStr-pStr;
372 pTempStr++;
375 return -1;
377 #endif
380 /* ----------------------------------------------------------------------- */
382 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
383 sal_Int32 nLen,
384 IMPL_RTL_STRCODE c )
385 SAL_THROW_EXTERN_C()
387 // assert(nLen >= 0);
388 #if !IMPL_RTL_IS_USTRING
389 // take advantage of builtin optimisations
390 IMPL_RTL_STRCODE* p = static_cast<IMPL_RTL_STRCODE*>(const_cast<void *>(memchr(pStr, c, nLen)));
391 return p ? p - pStr : -1;
392 #else
393 const IMPL_RTL_STRCODE* pTempStr = pStr;
394 while ( nLen > 0 )
396 if ( *pTempStr == c )
397 return pTempStr-pStr;
399 pTempStr++;
400 nLen--;
403 return -1;
404 #endif
407 /* ----------------------------------------------------------------------- */
409 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
410 IMPL_RTL_STRCODE c )
411 SAL_THROW_EXTERN_C()
413 assert(pStr);
414 #if !IMPL_RTL_IS_USTRING
415 // take advantage of builtin optimisations
416 const IMPL_RTL_STRCODE* p = strrchr(pStr, c);
417 return p ? p - pStr : -1;
418 #else
419 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
421 // take advantage of builtin optimisations
422 wchar_t const * p = wcsrchr(reinterpret_cast<wchar_t const *>(pStr), (wchar_t)c);
423 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
425 else
427 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
429 #endif
432 /* ----------------------------------------------------------------------- */
434 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
435 sal_Int32 nLen,
436 IMPL_RTL_STRCODE c )
437 SAL_THROW_EXTERN_C()
439 assert(nLen >= 0);
440 pStr += nLen;
441 while ( nLen > 0 )
443 nLen--;
444 pStr--;
446 if ( *pStr == c )
447 return nLen;
450 return -1;
453 /* ----------------------------------------------------------------------- */
455 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
456 const IMPL_RTL_STRCODE* pSubStr )
457 SAL_THROW_EXTERN_C()
459 assert(pStr);
460 assert(pSubStr);
461 #if !IMPL_RTL_IS_USTRING
462 // take advantage of builtin optimisations
463 const IMPL_RTL_STRCODE* p = strstr(pStr, pSubStr);
464 return p ? p - pStr : -1;
465 #else
466 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
468 // take advantage of builtin optimisations
469 wchar_t const * p = wcsstr(reinterpret_cast<wchar_t const *>(pStr), reinterpret_cast<wchar_t const *>(pSubStr));
470 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
472 else
474 return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
475 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
477 #endif
480 /* ----------------------------------------------------------------------- */
482 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
483 sal_Int32 nStrLen,
484 const IMPL_RTL_STRCODE* pSubStr,
485 sal_Int32 nSubLen )
486 SAL_THROW_EXTERN_C()
488 assert(nStrLen >= 0);
489 assert(nSubLen >= 0);
490 /* faster search for a single character */
491 if ( nSubLen < 2 )
493 /* an empty SubString is always not findable */
494 if ( nSubLen == 1 )
496 IMPL_RTL_STRCODE c = *pSubStr;
497 const IMPL_RTL_STRCODE* pTempStr = pStr;
498 while ( nStrLen > 0 )
500 if ( *pTempStr == c )
501 return pTempStr-pStr;
503 pTempStr++;
504 nStrLen--;
508 else
510 const IMPL_RTL_STRCODE* pTempStr = pStr;
511 while ( nStrLen > 0 )
513 if ( *pTempStr == *pSubStr )
515 /* Compare SubString */
516 if ( nSubLen <= nStrLen )
518 const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
519 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
520 sal_Int32 nTempLen = nSubLen;
521 while ( nTempLen )
523 if ( *pTempStr1 != *pTempStr2 )
524 break;
526 pTempStr1++;
527 pTempStr2++;
528 nTempLen--;
531 if ( !nTempLen )
532 return pTempStr-pStr;
534 else
535 break;
538 nStrLen--;
539 pTempStr++;
543 return -1;
546 /* ----------------------------------------------------------------------- */
548 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
549 const IMPL_RTL_STRCODE* pSubStr )
550 SAL_THROW_EXTERN_C()
552 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
553 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
556 /* ----------------------------------------------------------------------- */
558 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
559 sal_Int32 nStrLen,
560 const IMPL_RTL_STRCODE* pSubStr,
561 sal_Int32 nSubLen )
562 SAL_THROW_EXTERN_C()
564 // assert(nStrLen >= 0);
565 assert(nSubLen >= 0);
566 /* faster search for a single character */
567 if ( nSubLen < 2 )
569 /* an empty SubString is always not findable */
570 if ( nSubLen == 1 )
572 IMPL_RTL_STRCODE c = *pSubStr;
573 pStr += nStrLen;
574 while ( nStrLen > 0 )
576 nStrLen--;
577 pStr--;
579 if ( *pStr == c )
580 return nStrLen;
584 else
586 pStr += nStrLen;
587 nStrLen -= nSubLen;
588 pStr -= nSubLen;
589 while ( nStrLen >= 0 )
591 const IMPL_RTL_STRCODE* pTempStr1 = pStr;
592 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
593 sal_Int32 nTempLen = nSubLen;
594 while ( nTempLen )
596 if ( *pTempStr1 != *pTempStr2 )
597 break;
599 pTempStr1++;
600 pTempStr2++;
601 nTempLen--;
604 if ( !nTempLen )
605 return nStrLen;
607 nStrLen--;
608 pStr--;
612 return -1;
615 /* ----------------------------------------------------------------------- */
617 void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
618 IMPL_RTL_STRCODE cOld,
619 IMPL_RTL_STRCODE cNew )
620 SAL_THROW_EXTERN_C()
622 assert(pStr);
623 while ( *pStr )
625 if ( *pStr == cOld )
626 *pStr = cNew;
628 pStr++;
632 /* ----------------------------------------------------------------------- */
634 void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
635 sal_Int32 nLen,
636 IMPL_RTL_STRCODE cOld,
637 IMPL_RTL_STRCODE cNew )
638 SAL_THROW_EXTERN_C()
640 assert(nLen >= 0);
641 while ( nLen > 0 )
643 if ( *pStr == cOld )
644 *pStr = cNew;
646 pStr++;
647 nLen--;
651 /* ----------------------------------------------------------------------- */
653 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
654 SAL_THROW_EXTERN_C()
656 assert(pStr);
657 while ( *pStr )
659 *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
661 pStr++;
665 /* ----------------------------------------------------------------------- */
667 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
668 sal_Int32 nLen )
669 SAL_THROW_EXTERN_C()
671 assert(nLen >= 0);
672 while ( nLen > 0 )
674 *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
676 pStr++;
677 nLen--;
681 /* ----------------------------------------------------------------------- */
683 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
684 SAL_THROW_EXTERN_C()
686 assert(pStr);
687 while ( *pStr )
689 *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
691 pStr++;
695 /* ----------------------------------------------------------------------- */
697 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
698 sal_Int32 nLen )
699 SAL_THROW_EXTERN_C()
701 assert(nLen >= 0);
702 while ( nLen > 0 )
704 *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
706 pStr++;
707 nLen--;
711 /* ----------------------------------------------------------------------- */
713 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
714 SAL_THROW_EXTERN_C()
716 return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
719 /* ----------------------------------------------------------------------- */
721 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
722 SAL_THROW_EXTERN_C()
724 assert(nLen >= 0);
725 sal_Int32 nPreSpaces = 0;
726 sal_Int32 nPostSpaces = 0;
727 sal_Int32 nIndex = nLen-1;
729 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
730 nPreSpaces++;
732 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
734 nPostSpaces++;
735 nIndex--;
738 if ( nPostSpaces )
740 nLen -= nPostSpaces;
741 *(pStr+nLen) = 0;
744 if ( nPreSpaces )
746 IMPL_RTL_STRCODE* pNewStr = pStr+nPreSpaces;
748 nLen -= nPreSpaces;
749 nIndex = nLen;
751 while ( nIndex )
753 *pStr = *pNewStr;
754 pStr++;
755 pNewStr++;
756 nIndex--;
758 *pStr = 0;
761 return nLen;
764 /* ----------------------------------------------------------------------- */
766 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
767 SAL_THROW_EXTERN_C()
769 assert(pStr);
770 if ( b )
772 *pStr = 't';
773 pStr++;
774 *pStr = 'r';
775 pStr++;
776 *pStr = 'u';
777 pStr++;
778 *pStr = 'e';
779 pStr++;
780 *pStr = 0;
781 return 4;
783 else
785 *pStr = 'f';
786 pStr++;
787 *pStr = 'a';
788 pStr++;
789 *pStr = 'l';
790 pStr++;
791 *pStr = 's';
792 pStr++;
793 *pStr = 'e';
794 pStr++;
795 *pStr = 0;
796 return 5;
800 /* ----------------------------------------------------------------------- */
802 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
803 IMPL_RTL_STRCODE c )
804 SAL_THROW_EXTERN_C()
806 assert(pStr);
807 *pStr++ = c;
808 *pStr = 0;
809 return 1;
812 /* ----------------------------------------------------------------------- */
814 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
815 sal_Int32 n,
816 sal_Int16 nRadix )
817 SAL_THROW_EXTERN_C()
819 assert(pStr);
820 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32];
821 sal_Char* pBuf = aBuf;
822 sal_Int32 nLen = 0;
823 sal_uInt32 nValue;
825 /* Radix must be valid */
826 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
827 nRadix = 10;
829 /* is value negativ */
830 if ( n < 0 )
832 *pStr = '-';
833 pStr++;
834 nLen++;
835 nValue = n == SAL_MIN_INT32 ? static_cast<sal_uInt32>(n) : -n;
837 else
838 nValue = n;
840 /* create a recursive buffer with all values, except the last one */
843 sal_Char nDigit = (sal_Char)(nValue % nRadix);
844 nValue /= nRadix;
845 if ( nDigit > 9 )
846 *pBuf = (nDigit-10) + 'a';
847 else
848 *pBuf = (nDigit + '0' );
849 pBuf++;
851 while ( nValue > 0 );
853 /* copy the values in the right direction into the destination buffer */
856 pBuf--;
857 *pStr = *pBuf;
858 pStr++;
859 nLen++;
861 while ( pBuf != aBuf );
862 *pStr = 0;
864 return nLen;
867 /* ----------------------------------------------------------------------- */
869 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
870 sal_Int64 n,
871 sal_Int16 nRadix )
872 SAL_THROW_EXTERN_C()
874 assert(pStr);
875 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64];
876 sal_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 negativ */
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 sal_Char nDigit = (sal_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 sal_Char aBuf[RTL_STR_MAX_VALUEOFUINT64];
931 sal_Char* pBuf = aBuf;
932 sal_Int32 nLen = 0;
933 sal_uInt64 nValue;
935 /* Radix must be valid */
936 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
937 nRadix = 10;
939 nValue = n;
941 /* create a recursive buffer with all values, except the last one */
944 sal_Char nDigit = (sal_Char)(nValue % nRadix);
945 nValue /= nRadix;
946 if ( nDigit > 9 )
947 *pBuf = (nDigit-10) + 'a';
948 else
949 *pBuf = (nDigit + '0' );
950 pBuf++;
952 while ( nValue > 0 );
954 /* copy the values in the right direction into the destination buffer */
957 pBuf--;
958 *pStr = *pBuf;
959 pStr++;
960 nLen++;
962 while ( pBuf != aBuf );
963 *pStr = 0;
965 return nLen;
968 /* ----------------------------------------------------------------------- */
970 sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
971 SAL_THROW_EXTERN_C()
973 assert(pStr);
974 if ( *pStr == '1' )
975 return sal_True;
977 if ( (*pStr == 'T') || (*pStr == 't') )
979 pStr++;
980 if ( (*pStr == 'R') || (*pStr == 'r') )
982 pStr++;
983 if ( (*pStr == 'U') || (*pStr == 'u') )
985 pStr++;
986 if ( (*pStr == 'E') || (*pStr == 'e') )
987 return sal_True;
992 return sal_False;
995 /* ----------------------------------------------------------------------- */
996 namespace {
997 template<typename T, typename U> static inline T IMPL_RTL_STRNAME( toInt )( const IMPL_RTL_STRCODE* pStr,
998 sal_Int16 nRadix )
1000 static_assert(std::numeric_limits<T>::is_signed, "is signed");
1001 bool bNeg;
1002 sal_Int16 nDigit;
1003 U n = 0;
1005 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1006 nRadix = 10;
1008 /* Skip whitespaces */
1009 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1010 pStr++;
1012 if ( *pStr == '-' )
1014 bNeg = true;
1015 pStr++;
1017 else
1019 if ( *pStr == '+' )
1020 pStr++;
1021 bNeg = false;
1024 T nDiv;
1025 sal_Int16 nMod;
1026 if ( bNeg )
1028 nDiv = std::numeric_limits<T>::min() / nRadix;
1029 nMod = std::numeric_limits<T>::min() % nRadix;
1030 // Cater for C++03 implementations that round the quotient down
1031 // instead of truncating towards zero as mandated by C++11:
1032 if ( nMod > 0 )
1034 --nDiv;
1035 nMod -= nRadix;
1037 nDiv = -nDiv;
1038 nMod = -nMod;
1040 else
1042 nDiv = std::numeric_limits<T>::max() / nRadix;
1043 nMod = std::numeric_limits<T>::max() % nRadix;
1046 while ( *pStr )
1048 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1049 if ( nDigit < 0 )
1050 break;
1051 assert(nDiv > 0);
1052 if( static_cast<U>( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1053 return 0;
1055 n *= nRadix;
1056 n += nDigit;
1058 pStr++;
1061 if ( bNeg )
1062 return n == static_cast<U>(std::numeric_limits<T>::min())
1063 ? std::numeric_limits<T>::min() : -static_cast<T>(n);
1064 else
1065 return static_cast<T>(n);
1069 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
1070 sal_Int16 nRadix )
1071 SAL_THROW_EXTERN_C()
1073 assert(pStr);
1074 return IMPL_RTL_STRNAME( toInt )<sal_Int32, sal_uInt32>(pStr, nRadix);
1077 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
1078 sal_Int16 nRadix )
1079 SAL_THROW_EXTERN_C()
1081 assert(pStr);
1082 return IMPL_RTL_STRNAME( toInt )<sal_Int64, sal_uInt64>(pStr, nRadix);
1085 /* ----------------------------------------------------------------------- */
1086 namespace {
1087 template <typename T> static inline T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr,
1088 sal_Int16 nRadix )
1090 static_assert(!std::numeric_limits<T>::is_signed, "is not signed");
1091 sal_Int16 nDigit;
1092 T n = 0;
1094 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1095 nRadix = 10;
1097 /* Skip whitespaces */
1098 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1099 ++pStr;
1101 // skip optional explicit sign
1102 if ( *pStr == '+' )
1103 ++pStr;
1105 T nDiv = std::numeric_limits<T>::max() / nRadix;
1106 sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix;
1107 while ( *pStr )
1109 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1110 if ( nDigit < 0 )
1111 break;
1112 if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1113 return 0;
1115 n *= nRadix;
1116 n += nDigit;
1118 ++pStr;
1121 return n;
1125 sal_uInt32 SAL_CALL IMPL_RTL_STRNAME( toUInt32 )( const IMPL_RTL_STRCODE* pStr,
1126 sal_Int16 nRadix )
1127 SAL_THROW_EXTERN_C()
1129 assert(pStr);
1130 return IMPL_RTL_STRNAME( toUInt )<sal_uInt32>(pStr, nRadix);
1133 sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr,
1134 sal_Int16 nRadix )
1135 SAL_THROW_EXTERN_C()
1137 assert(pStr);
1138 return IMPL_RTL_STRNAME( toUInt )<sal_uInt64>(pStr, nRadix);
1141 /* ======================================================================= */
1142 /* Internal String-Class help functions */
1143 /* ======================================================================= */
1145 static IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
1147 IMPL_RTL_STRINGDATA * pData
1148 = (sal::static_int_cast< sal_uInt32 >(nLen)
1149 <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
1150 / sizeof (IMPL_RTL_STRCODE)))
1151 ? static_cast<IMPL_RTL_STRINGDATA *>(rtl_allocateMemory(
1152 sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)))
1153 : NULL;
1154 if (pData != NULL) {
1155 pData->refCount = 1;
1156 pData->length = nLen;
1157 pData->buffer[nLen] = 0;
1159 return pData;
1162 /* ----------------------------------------------------------------------- */
1164 static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
1165 IMPL_RTL_STRINGDATA* pStr,
1166 sal_Int32 nCount )
1168 assert(nCount >= 0);
1169 IMPL_RTL_STRCODE* pDest;
1170 const IMPL_RTL_STRCODE* pSrc;
1171 IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1172 OSL_ASSERT(pData != NULL);
1174 pDest = pData->buffer;
1175 pSrc = pStr->buffer;
1176 while ( nCount > 0 )
1178 *pDest = *pSrc;
1179 pDest++;
1180 pSrc++;
1181 nCount--;
1184 *ppThis = pData;
1186 RTL_LOG_STRING_NEW( pData );
1187 return pDest;
1190 /* ======================================================================= */
1191 /* String-Class functions */
1192 /* ======================================================================= */
1194 namespace {
1196 void IMPL_RTL_ACQUIRE(IMPL_RTL_STRINGDATA * pThis)
1198 if (!SAL_STRING_IS_STATIC (pThis))
1199 osl_atomic_increment( &((pThis)->refCount) );
1204 /* ----------------------------------------------------------------------- */
1206 void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
1207 SAL_THROW_EXTERN_C()
1209 IMPL_RTL_ACQUIRE( pThis );
1212 /* ----------------------------------------------------------------------- */
1214 void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
1215 SAL_THROW_EXTERN_C()
1217 if (SAL_STRING_IS_STATIC (pThis))
1218 return;
1220 /* OString doesn't have an 'intern' */
1221 #if IMPL_RTL_IS_USTRING
1222 if (SAL_STRING_IS_INTERN (pThis))
1224 internRelease (pThis);
1225 return;
1227 #endif
1229 if ( !osl_atomic_decrement( &(pThis->refCount) ) )
1231 RTL_LOG_STRING_DELETE( pThis );
1232 rtl_freeMemory( pThis );
1236 /* ----------------------------------------------------------------------- */
1238 void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
1239 SAL_THROW_EXTERN_C()
1241 assert(ppThis);
1242 if ( *ppThis)
1243 IMPL_RTL_STRINGNAME( release )( *ppThis );
1245 *ppThis = const_cast<IMPL_RTL_STRINGDATA*>(&IMPL_RTL_EMPTYSTRING);
1248 /* ----------------------------------------------------------------------- */
1250 IMPL_RTL_STRINGDATA* SAL_CALL IMPL_RTL_STRINGNAME( alloc )( sal_Int32 nLen )
1251 SAL_THROW_EXTERN_C()
1253 if ( nLen < 0 )
1254 return NULL;
1255 else
1256 return IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1259 /* ----------------------------------------------------------------------- */
1261 void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
1262 SAL_THROW_EXTERN_C()
1264 assert(ppThis);
1265 if ( nLen <= 0 )
1266 IMPL_RTL_STRINGNAME( new )( ppThis );
1267 else
1269 if ( *ppThis)
1270 IMPL_RTL_STRINGNAME( release )( *ppThis );
1272 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1273 OSL_ASSERT(*ppThis != NULL);
1274 (*ppThis)->length = 0;
1276 IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
1277 memset(pTempStr, 0, nLen*sizeof(IMPL_RTL_STRCODE));
1281 /* ----------------------------------------------------------------------- */
1283 void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
1284 const IMPL_RTL_STRINGDATA* pStr )
1285 SAL_THROW_EXTERN_C()
1287 assert(ppThis);
1288 assert(pStr);
1289 IMPL_RTL_STRINGDATA* pOrg;
1291 if ( !pStr->length )
1293 IMPL_RTL_STRINGNAME( new )( ppThis );
1294 return;
1297 pOrg = *ppThis;
1298 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1299 OSL_ASSERT(*ppThis != NULL);
1300 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
1301 RTL_LOG_STRING_NEW( *ppThis );
1303 /* must be done last, if pStr == *ppThis */
1304 if ( pOrg )
1305 IMPL_RTL_STRINGNAME( release )( pOrg );
1308 /* ----------------------------------------------------------------------- */
1310 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
1311 const IMPL_RTL_STRCODE* pCharStr )
1312 SAL_THROW_EXTERN_C()
1314 assert(ppThis);
1315 IMPL_RTL_STRCODE* pBuffer;
1316 IMPL_RTL_STRINGDATA* pOrg;
1317 sal_Int32 nLen;
1319 if ( pCharStr )
1321 const IMPL_RTL_STRCODE* pTempStr = pCharStr;
1322 while( *pTempStr )
1323 pTempStr++;
1324 nLen = pTempStr-pCharStr;
1326 else
1327 nLen = 0;
1329 if ( !nLen )
1331 IMPL_RTL_STRINGNAME( new )( ppThis );
1332 return;
1335 pOrg = *ppThis;
1336 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1337 OSL_ASSERT(*ppThis != NULL);
1338 pBuffer = (*ppThis)->buffer;
1341 *pBuffer = *pCharStr;
1342 pBuffer++;
1343 pCharStr++;
1345 while ( *pCharStr );
1347 RTL_LOG_STRING_NEW( *ppThis );
1349 /* must be done last, if pCharStr == *ppThis */
1350 if ( pOrg )
1351 IMPL_RTL_STRINGNAME( release )( pOrg );
1354 /* ----------------------------------------------------------------------- */
1356 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
1357 const IMPL_RTL_STRCODE* pCharStr,
1358 sal_Int32 nLen )
1359 SAL_THROW_EXTERN_C()
1361 assert(ppThis);
1362 IMPL_RTL_STRINGDATA* pOrg;
1364 if ( !pCharStr || (nLen <= 0) )
1366 IMPL_RTL_STRINGNAME( new )( ppThis );
1367 return;
1370 pOrg = *ppThis;
1371 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1372 OSL_ASSERT(*ppThis != NULL);
1373 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1375 RTL_LOG_STRING_NEW( *ppThis );
1377 /* must be done last, if pCharStr == *ppThis */
1378 if ( pOrg )
1379 IMPL_RTL_STRINGNAME( release )( pOrg );
1382 /* ----------------------------------------------------------------------- */
1384 void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis,
1385 const IMPL_RTL_STRINGDATA* pFrom,
1386 sal_Int32 beginIndex,
1387 sal_Int32 count )
1388 SAL_THROW_EXTERN_C()
1390 assert(ppThis);
1391 if ( beginIndex == 0 && count == pFrom->length )
1393 IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) );
1394 return;
1396 if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length )
1398 assert(false); // fail fast at least in debug builds
1399 IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 );
1400 return;
1403 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count );
1406 /* ----------------------------------------------------------------------- */
1408 // Used when creating from string literals.
1409 void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis,
1410 const sal_Char* pCharStr,
1411 sal_Int32 nLen,
1412 sal_Int32 allocExtra )
1413 SAL_THROW_EXTERN_C()
1415 assert(ppThis);
1416 assert(nLen >= 0);
1417 assert(allocExtra >= 0);
1418 if ( nLen + allocExtra == 0 )
1420 IMPL_RTL_STRINGNAME( new )( ppThis );
1421 return;
1424 if ( *ppThis )
1425 IMPL_RTL_STRINGNAME( release )( *ppThis );
1427 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra );
1428 assert( *ppThis != NULL );
1430 (*ppThis)->length = nLen; // fix after possible allocExtra != 0
1431 (*ppThis)->buffer[nLen] = 0;
1432 IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
1433 sal_Int32 nCount;
1434 for( nCount = nLen; nCount > 0; --nCount )
1436 #if IMPL_RTL_IS_USTRING
1437 assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
1438 #endif
1439 SAL_WARN_IF( ((unsigned char)*pCharStr) == '\0', "rtl.string",
1440 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1442 *pBuffer = *pCharStr;
1443 pBuffer++;
1444 pCharStr++;
1447 RTL_LOG_STRING_NEW( *ppThis );
1450 /* ----------------------------------------------------------------------- */
1452 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
1453 IMPL_RTL_STRINGDATA* pStr )
1454 SAL_THROW_EXTERN_C()
1456 assert(ppThis);
1457 /* must be done at first, if pStr == *ppThis */
1458 IMPL_RTL_ACQUIRE( pStr );
1460 if ( *ppThis )
1461 IMPL_RTL_STRINGNAME( release )( *ppThis );
1463 *ppThis = pStr;
1466 /* ----------------------------------------------------------------------- */
1468 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
1469 SAL_THROW_EXTERN_C()
1471 assert(pThis);
1472 return pThis->length;
1475 /* ----------------------------------------------------------------------- */
1477 IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
1478 SAL_THROW_EXTERN_C()
1480 assert(pThis);
1481 return pThis->buffer;
1484 /* ----------------------------------------------------------------------- */
1486 void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
1487 IMPL_RTL_STRINGDATA* pLeft,
1488 IMPL_RTL_STRINGDATA* pRight )
1489 SAL_THROW_EXTERN_C()
1491 assert(ppThis);
1492 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1494 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1495 if ( !pRight || !pRight->length )
1497 *ppThis = pLeft;
1498 IMPL_RTL_ACQUIRE( pLeft );
1500 else if ( !pLeft || !pLeft->length )
1502 *ppThis = pRight;
1503 IMPL_RTL_ACQUIRE( pRight );
1505 else
1507 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
1508 OSL_ASSERT(pTempStr != NULL);
1509 rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
1510 rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
1511 *ppThis = pTempStr;
1513 RTL_LOG_STRING_NEW( *ppThis );
1516 /* must be done last, if left or right == *ppThis */
1517 if ( pOrg )
1518 IMPL_RTL_STRINGNAME( release )( pOrg );
1521 /* ----------------------------------------------------------------------- */
1523 void SAL_CALL IMPL_RTL_STRINGNAME( ensureCapacity )( IMPL_RTL_STRINGDATA** ppThis,
1524 sal_Int32 size )
1525 SAL_THROW_EXTERN_C()
1527 assert(ppThis);
1528 IMPL_RTL_STRINGDATA* const pOrg = *ppThis;
1529 if ( pOrg->refCount == 1 && pOrg->length >= size )
1530 return;
1531 assert( pOrg->length <= size ); // do not truncate
1532 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( size );
1533 rtl_str_ImplCopy( pTempStr->buffer, pOrg->buffer, pOrg->length );
1534 // right now the length is still the same as of the original
1535 pTempStr->length = pOrg->length;
1536 pTempStr->buffer[ pOrg->length ] = '\0';
1537 *ppThis = pTempStr;
1538 RTL_LOG_STRING_NEW( *ppThis );
1540 IMPL_RTL_STRINGNAME( release )( pOrg );
1543 /* ----------------------------------------------------------------------- */
1545 void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
1546 IMPL_RTL_STRINGDATA* pStr,
1547 sal_Int32 nIndex,
1548 sal_Int32 nCount,
1549 IMPL_RTL_STRINGDATA* pNewSubStr )
1550 SAL_THROW_EXTERN_C()
1552 assert(ppThis);
1553 // assert(nCount >= 0);
1554 /* Append? */
1555 if ( nIndex >= pStr->length )
1557 /* newConcat test, if pNewSubStr is 0 */
1558 IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
1559 return;
1562 /* negativ index? */
1563 if ( nIndex < 0 )
1565 nCount -= nIndex;
1566 nIndex = 0;
1569 /* not more than the String length could be deleted */
1570 if ( nCount >= pStr->length-nIndex )
1572 nCount = pStr->length-nIndex;
1574 /* Assign of NewSubStr? */
1575 if ( !nIndex && (nCount >= pStr->length) )
1577 if ( !pNewSubStr )
1578 IMPL_RTL_STRINGNAME( new )( ppThis );
1579 else
1580 IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
1581 return;
1585 /* Assign of Str? */
1586 if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
1588 IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
1589 return;
1592 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1593 IMPL_RTL_STRCODE* pBuffer;
1594 sal_Int32 nNewLen;
1596 /* Calculate length of the new string */
1597 nNewLen = pStr->length-nCount;
1598 if ( pNewSubStr )
1599 nNewLen += pNewSubStr->length;
1601 /* Alloc New Buffer */
1602 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
1603 OSL_ASSERT(*ppThis != NULL);
1604 pBuffer = (*ppThis)->buffer;
1605 if ( nIndex )
1607 rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
1608 pBuffer += nIndex;
1610 if ( pNewSubStr && pNewSubStr->length )
1612 rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
1613 pBuffer += pNewSubStr->length;
1615 rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
1617 RTL_LOG_STRING_NEW( *ppThis );
1618 /* must be done last, if pStr or pNewSubStr == *ppThis */
1619 if ( pOrg )
1620 IMPL_RTL_STRINGNAME( release )( pOrg );
1623 /* ----------------------------------------------------------------------- */
1625 void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
1626 IMPL_RTL_STRINGDATA* pStr,
1627 IMPL_RTL_STRCODE cOld,
1628 IMPL_RTL_STRCODE cNew )
1629 SAL_THROW_EXTERN_C()
1631 assert(ppThis);
1632 assert(pStr);
1633 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1634 int bChanged = 0;
1635 sal_Int32 nLen = pStr->length;
1636 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1638 while ( nLen > 0 )
1640 if ( *pCharStr == cOld )
1642 /* Copy String */
1643 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1645 /* replace/copy rest of the string */
1646 if ( pNewCharStr )
1648 *pNewCharStr = cNew;
1649 pNewCharStr++;
1650 pCharStr++;
1651 nLen--;
1653 while ( nLen > 0 )
1655 if ( *pCharStr == cOld )
1656 *pNewCharStr = cNew;
1657 else
1658 *pNewCharStr = *pCharStr;
1660 pNewCharStr++;
1661 pCharStr++;
1662 nLen--;
1666 bChanged = 1;
1667 break;
1670 pCharStr++;
1671 nLen--;
1674 if ( !bChanged )
1676 *ppThis = pStr;
1677 IMPL_RTL_ACQUIRE( pStr );
1680 RTL_LOG_STRING_NEW( *ppThis );
1681 /* must be done last, if pStr == *ppThis */
1682 if ( pOrg )
1683 IMPL_RTL_STRINGNAME( release )( pOrg );
1686 /* ----------------------------------------------------------------------- */
1688 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
1689 IMPL_RTL_STRINGDATA* pStr )
1690 SAL_THROW_EXTERN_C()
1692 assert(ppThis);
1693 assert(pStr);
1694 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1695 int bChanged = 0;
1696 sal_Int32 nLen = pStr->length;
1697 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1699 while ( nLen > 0 )
1701 if ( rtl::isAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1703 /* Copy String */
1704 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1706 /* replace/copy rest of the string */
1707 if ( pNewCharStr )
1709 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1710 pNewCharStr++;
1711 pCharStr++;
1712 nLen--;
1714 while ( nLen > 0 )
1716 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1718 pNewCharStr++;
1719 pCharStr++;
1720 nLen--;
1724 bChanged = 1;
1725 break;
1728 pCharStr++;
1729 nLen--;
1732 if ( !bChanged )
1734 *ppThis = pStr;
1735 IMPL_RTL_ACQUIRE( pStr );
1738 RTL_LOG_STRING_NEW( *ppThis );
1739 /* must be done last, if pStr == *ppThis */
1740 if ( pOrg )
1741 IMPL_RTL_STRINGNAME( release )( pOrg );
1744 /* ----------------------------------------------------------------------- */
1746 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
1747 IMPL_RTL_STRINGDATA* pStr )
1748 SAL_THROW_EXTERN_C()
1750 assert(ppThis);
1751 assert(pStr);
1752 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1753 int bChanged = 0;
1754 sal_Int32 nLen = pStr->length;
1755 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1757 while ( nLen > 0 )
1759 if ( rtl::isAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1761 /* Copy String */
1762 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1764 /* replace/copy rest of the string */
1765 if ( pNewCharStr )
1767 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1768 pNewCharStr++;
1769 pCharStr++;
1770 nLen--;
1772 while ( nLen > 0 )
1774 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1776 pNewCharStr++;
1777 pCharStr++;
1778 nLen--;
1782 bChanged = 1;
1783 break;
1786 pCharStr++;
1787 nLen--;
1790 if ( !bChanged )
1792 *ppThis = pStr;
1793 IMPL_RTL_ACQUIRE( pStr );
1796 RTL_LOG_STRING_NEW( *ppThis );
1797 /* must be done last, if pStr == *ppThis */
1798 if ( pOrg )
1799 IMPL_RTL_STRINGNAME( release )( pOrg );
1802 /* ----------------------------------------------------------------------- */
1804 void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
1805 IMPL_RTL_STRINGDATA* pStr )
1806 SAL_THROW_EXTERN_C()
1808 assert(ppThis);
1809 assert(pStr);
1810 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1811 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1812 sal_Int32 nPreSpaces = 0;
1813 sal_Int32 nPostSpaces = 0;
1814 sal_Int32 nLen = pStr->length;
1815 sal_Int32 nIndex = nLen-1;
1817 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
1818 nPreSpaces++;
1820 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
1822 nPostSpaces++;
1823 nIndex--;
1826 if ( !nPreSpaces && !nPostSpaces )
1828 *ppThis = pStr;
1829 IMPL_RTL_ACQUIRE( pStr );
1831 else
1833 nLen -= nPostSpaces+nPreSpaces;
1834 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1835 assert(*ppThis);
1836 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
1839 RTL_LOG_STRING_NEW( *ppThis );
1840 /* must be done last, if pStr == *ppThis */
1841 if ( pOrg )
1842 IMPL_RTL_STRINGNAME( release )( pOrg );
1845 /* ----------------------------------------------------------------------- */
1847 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
1848 IMPL_RTL_STRINGDATA* pStr,
1849 sal_Int32 nToken,
1850 IMPL_RTL_STRCODE cTok,
1851 sal_Int32 nIndex )
1852 SAL_THROW_EXTERN_C()
1854 assert(ppThis);
1855 assert(pStr);
1856 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1857 const IMPL_RTL_STRCODE* pCharStrStart;
1858 const IMPL_RTL_STRCODE* pOrgCharStr;
1859 sal_Int32 nLen = pStr->length-nIndex;
1860 sal_Int32 nTokCount = 0;
1862 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1863 // negative:
1864 if (nIndex < 0)
1865 nToken = -1;
1867 pCharStr += nIndex;
1868 pOrgCharStr = pCharStr;
1869 pCharStrStart = pCharStr;
1870 while ( nLen > 0 )
1872 if ( *pCharStr == cTok )
1874 nTokCount++;
1876 if ( nTokCount == nToken )
1877 pCharStrStart = pCharStr+1;
1878 else
1880 if ( nTokCount > nToken )
1881 break;
1885 pCharStr++;
1886 nLen--;
1889 if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
1891 IMPL_RTL_STRINGNAME( new )( ppThis );
1892 if( (nToken < 0) || (nTokCount < nToken ) )
1893 return -1;
1894 else if( nLen > 0 )
1895 return nIndex+(pCharStr-pOrgCharStr)+1;
1896 else return -1;
1898 else
1900 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
1901 if ( nLen )
1902 return nIndex+(pCharStr-pOrgCharStr)+1;
1903 else
1904 return -1;
1908 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */