1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 */
23 /* ======================================================================= */
26 #include <sal/log.hxx>
28 #include <boost/static_assert.hpp>
31 inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
32 const IMPL_RTL_STRCODE* pSrc,
45 #define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \
47 IMPL_RTL_STRCODE* __mm_pDest = _pDest; \
48 const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \
49 sal_Int32 __mm_nCount = _nCount; \
50 while ( __mm_nCount > 0 ) \
52 *__mm_pDest = *__mm_pSrc; \
59 /* ======================================================================= */
60 /* C-String functions which could be used without the String-Class */
61 /* ======================================================================= */
63 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( getLength
)( const IMPL_RTL_STRCODE
* pStr
)
66 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
72 /* ----------------------------------------------------------------------- */
74 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compare
)( const IMPL_RTL_STRCODE
* pStr1
,
75 const IMPL_RTL_STRCODE
* pStr2
)
79 while ( ((nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE(*pStr1
)))-
80 ((sal_Int32
)(IMPL_RTL_USTRCODE(*pStr2
)))) == 0) &&
90 /* ----------------------------------------------------------------------- */
92 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compare_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
94 const IMPL_RTL_STRCODE
* pStr2
,
98 sal_Int32 nRet
= nStr1Len
- nStr2Len
;
99 int nCount
= (nRet
<= 0) ? nStr1Len
: nStr2Len
;
103 while( (--nCount
>= 0) && (*++pStr1
== *++pStr2
) ) ;
106 nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr1
)))
107 - ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr2
)));
112 /* ----------------------------------------------------------------------- */
114 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( shortenedCompare_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
116 const IMPL_RTL_STRCODE
* pStr2
,
118 sal_Int32 nShortenedLength
)
121 const IMPL_RTL_STRCODE
* pStr1End
= pStr1
+ nStr1Len
;
122 const IMPL_RTL_STRCODE
* pStr2End
= pStr2
+ nStr2Len
;
124 while ( (nShortenedLength
> 0) &&
125 (pStr1
< pStr1End
) && (pStr2
< pStr2End
) )
127 nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr1
)))-
128 ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr2
)));
137 if ( nShortenedLength
<= 0 )
139 return nStr1Len
- nStr2Len
;
142 /* ----------------------------------------------------------------------- */
144 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( reverseCompare_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
146 const IMPL_RTL_STRCODE
* pStr2
,
150 const IMPL_RTL_STRCODE
* pStr1Run
= pStr1
+nStr1Len
;
151 const IMPL_RTL_STRCODE
* pStr2Run
= pStr2
+nStr2Len
;
153 while ( (pStr1
< pStr1Run
) && (pStr2
< pStr2Run
) )
157 nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr1Run
)))-
158 ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr2Run
)));
163 return nStr1Len
- nStr2Len
;
166 /* ----------------------------------------------------------------------- */
168 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compareIgnoreAsciiCase
)( const IMPL_RTL_STRCODE
* pStr1
,
169 const IMPL_RTL_STRCODE
* pStr2
)
177 /* If character between 'A' and 'Z', than convert it to lowercase */
178 c1
= (sal_Int32
)IMPL_RTL_USTRCODE( *pStr1
);
179 c2
= (sal_Int32
)IMPL_RTL_USTRCODE( *pStr2
);
180 if ( (c1
>= 65) && (c1
<= 90) )
182 if ( (c2
>= 65) && (c2
<= 90) )
196 /* ----------------------------------------------------------------------- */
198 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
200 const IMPL_RTL_STRCODE
* pStr2
,
204 const IMPL_RTL_STRCODE
* pStr1End
= pStr1
+ nStr1Len
;
205 const IMPL_RTL_STRCODE
* pStr2End
= pStr2
+ nStr2Len
;
209 while ( (pStr1
< pStr1End
) && (pStr2
< pStr2End
) )
211 /* If character between 'A' and 'Z', than convert it to lowercase */
212 c1
= (sal_Int32
)IMPL_RTL_USTRCODE( *pStr1
);
213 c2
= (sal_Int32
)IMPL_RTL_USTRCODE( *pStr2
);
214 if ( (c1
>= 65) && (c1
<= 90) )
216 if ( (c2
>= 65) && (c2
<= 90) )
226 return nStr1Len
- nStr2Len
;
229 /* ----------------------------------------------------------------------- */
231 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
233 const IMPL_RTL_STRCODE
* pStr2
,
235 sal_Int32 nShortenedLength
)
238 const IMPL_RTL_STRCODE
* pStr1End
= pStr1
+ nStr1Len
;
239 const IMPL_RTL_STRCODE
* pStr2End
= pStr2
+ nStr2Len
;
243 while ( (nShortenedLength
> 0) &&
244 (pStr1
< pStr1End
) && (pStr2
< pStr2End
) )
246 /* If character between 'A' and 'Z', than convert it to lowercase */
247 c1
= (sal_Int32
)IMPL_RTL_USTRCODE( *pStr1
);
248 c2
= (sal_Int32
)IMPL_RTL_USTRCODE( *pStr2
);
249 if ( (c1
>= 65) && (c1
<= 90) )
251 if ( (c2
>= 65) && (c2
<= 90) )
262 if ( nShortenedLength
<= 0 )
264 return nStr1Len
- nStr2Len
;
267 /* ----------------------------------------------------------------------- */
269 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( hashCode
)( const IMPL_RTL_STRCODE
* pStr
)
272 return IMPL_RTL_STRNAME( hashCode_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
) );
275 /* ----------------------------------------------------------------------- */
277 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( hashCode_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
287 h
= (h
*37) + IMPL_RTL_USTRCODE( *pStr
);
295 const IMPL_RTL_STRCODE
* pEndStr
= pStr
+nLen
-5;
297 /* only sample some characters */
298 /* the first 3, some characters between, and the last 5 */
299 h
= (h
*39) + IMPL_RTL_USTRCODE( *pStr
);
301 h
= (h
*39) + IMPL_RTL_USTRCODE( *pStr
);
303 h
= (h
*39) + IMPL_RTL_USTRCODE( *pStr
);
310 h
= (h
*39) + IMPL_RTL_USTRCODE( *pStr
);
315 h
= (h
*39) + IMPL_RTL_USTRCODE( *pEndStr
);
317 h
= (h
*39) + IMPL_RTL_USTRCODE( *pEndStr
);
319 h
= (h
*39) + IMPL_RTL_USTRCODE( *pEndStr
);
321 h
= (h
*39) + IMPL_RTL_USTRCODE( *pEndStr
);
323 h
= (h
*39) + IMPL_RTL_USTRCODE( *pEndStr
);
329 /* ----------------------------------------------------------------------- */
331 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfChar
)( const IMPL_RTL_STRCODE
* pStr
,
335 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
338 if ( *pTempStr
== c
)
339 return pTempStr
-pStr
;
347 /* ----------------------------------------------------------------------- */
349 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfChar_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
354 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
357 if ( *pTempStr
== c
)
358 return pTempStr
-pStr
;
367 /* ----------------------------------------------------------------------- */
369 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfChar
)( const IMPL_RTL_STRCODE
* pStr
,
373 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
), c
);
376 /* ----------------------------------------------------------------------- */
378 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfChar_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
396 /* ----------------------------------------------------------------------- */
398 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfStr
)( const IMPL_RTL_STRCODE
* pStr
,
399 const IMPL_RTL_STRCODE
* pSubStr
)
402 return IMPL_RTL_STRNAME( indexOfStr_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
),
403 pSubStr
, IMPL_RTL_STRNAME( getLength
)( pSubStr
) );
406 /* ----------------------------------------------------------------------- */
408 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfStr_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
410 const IMPL_RTL_STRCODE
* pSubStr
,
414 /* faster search for a single character */
417 /* an empty SubString is always not foundable */
420 IMPL_RTL_STRCODE c
= *pSubStr
;
421 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
422 while ( nStrLen
> 0 )
424 if ( *pTempStr
== c
)
425 return pTempStr
-pStr
;
434 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
435 while ( nStrLen
> 0 )
437 if ( *pTempStr
== *pSubStr
)
439 /* Compare SubString */
440 if ( nSubLen
<= nStrLen
)
442 const IMPL_RTL_STRCODE
* pTempStr1
= pTempStr
;
443 const IMPL_RTL_STRCODE
* pTempStr2
= pSubStr
;
444 sal_Int32 nTempLen
= nSubLen
;
447 if ( *pTempStr1
!= *pTempStr2
)
456 return pTempStr
-pStr
;
470 /* ----------------------------------------------------------------------- */
472 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfStr
)( const IMPL_RTL_STRCODE
* pStr
,
473 const IMPL_RTL_STRCODE
* pSubStr
)
476 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
),
477 pSubStr
, IMPL_RTL_STRNAME( getLength
)( pSubStr
) );
480 /* ----------------------------------------------------------------------- */
482 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfStr_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
484 const IMPL_RTL_STRCODE
* pSubStr
,
488 /* faster search for a single character */
491 /* an empty SubString is always not foundable */
494 IMPL_RTL_STRCODE c
= *pSubStr
;
496 while ( nStrLen
> 0 )
511 while ( nStrLen
>= 0 )
513 const IMPL_RTL_STRCODE
* pTempStr1
= pStr
;
514 const IMPL_RTL_STRCODE
* pTempStr2
= pSubStr
;
515 sal_Int32 nTempLen
= nSubLen
;
518 if ( *pTempStr1
!= *pTempStr2
)
537 /* ----------------------------------------------------------------------- */
539 void SAL_CALL
IMPL_RTL_STRNAME( replaceChar
)( IMPL_RTL_STRCODE
* pStr
,
540 IMPL_RTL_STRCODE cOld
,
541 IMPL_RTL_STRCODE cNew
)
553 /* ----------------------------------------------------------------------- */
555 void SAL_CALL
IMPL_RTL_STRNAME( replaceChar_WithLength
)( IMPL_RTL_STRCODE
* pStr
,
557 IMPL_RTL_STRCODE cOld
,
558 IMPL_RTL_STRCODE cNew
)
571 /* ----------------------------------------------------------------------- */
573 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiLowerCase
)( IMPL_RTL_STRCODE
* pStr
)
578 /* Between A-Z (65-90), than to lowercase (+32) */
579 if ( (*pStr
>= 65) && (*pStr
<= 90) )
586 /* ----------------------------------------------------------------------- */
588 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength
)( IMPL_RTL_STRCODE
* pStr
,
594 /* Between A-Z (65-90), than to lowercase (+32) */
595 if ( (*pStr
>= 65) && (*pStr
<= 90) )
603 /* ----------------------------------------------------------------------- */
605 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiUpperCase
)( IMPL_RTL_STRCODE
* pStr
)
610 /* Between a-z (97-122), than to uppercase (-32) */
611 if ( (*pStr
>= 97) && (*pStr
<= 122) )
618 /* ----------------------------------------------------------------------- */
620 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength
)( IMPL_RTL_STRCODE
* pStr
,
626 /* Between a-z (97-122), than to uppercase (-32) */
627 if ( (*pStr
>= 97) && (*pStr
<= 122) )
635 /* ----------------------------------------------------------------------- */
637 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( trim
)( IMPL_RTL_STRCODE
* pStr
)
640 return IMPL_RTL_STRNAME( trim_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
) );
643 /* ----------------------------------------------------------------------- */
645 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( trim_WithLength
)( IMPL_RTL_STRCODE
* pStr
, sal_Int32 nLen
)
648 sal_Int32 nPreSpaces
= 0;
649 sal_Int32 nPostSpaces
= 0;
650 sal_Int32 nIndex
= nLen
-1;
652 while ( (nPreSpaces
< nLen
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr
+nPreSpaces
)) ) )
655 while ( (nIndex
> nPreSpaces
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr
+nIndex
)) ) )
669 IMPL_RTL_STRCODE
* pNewStr
= pStr
+nPreSpaces
;
687 /* ----------------------------------------------------------------------- */
689 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfBoolean
)( IMPL_RTL_STRCODE
* pStr
, sal_Bool b
)
722 /* ----------------------------------------------------------------------- */
724 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfChar
)( IMPL_RTL_STRCODE
* pStr
,
733 /* ----------------------------------------------------------------------- */
735 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfInt32
)( IMPL_RTL_STRCODE
* pStr
,
740 sal_Char aBuf
[RTL_STR_MAX_VALUEOFINT32
];
741 sal_Char
* pBuf
= aBuf
;
745 /* Radix must be valid */
746 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
749 /* is value negativ */
755 nValue
= -n
; /* FIXME this code is not portable for n == -2147483648
756 (smallest negative value for sal_Int32) */
761 /* create a recursive buffer with all values, except the last one */
764 sal_Char nDigit
= (sal_Char
)(nValue
% nRadix
);
767 *pBuf
= (nDigit
-10) + 'a';
769 *pBuf
= (nDigit
+ '0' );
772 while ( nValue
> 0 );
774 /* copy the values in the right direction into the destination buffer */
782 while ( pBuf
!= aBuf
);
788 /* ----------------------------------------------------------------------- */
790 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfInt64
)( IMPL_RTL_STRCODE
* pStr
,
795 sal_Char aBuf
[RTL_STR_MAX_VALUEOFINT64
];
796 sal_Char
* pBuf
= aBuf
;
800 /* Radix must be valid */
801 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
804 /* is value negativ */
810 nValue
= -n
; /* FIXME this code is not portable for
811 n == -9223372036854775808 (smallest negative value for
817 /* create a recursive buffer with all values, except the last one */
820 sal_Char nDigit
= (sal_Char
)(nValue
% nRadix
);
823 *pBuf
= (nDigit
-10) + 'a';
825 *pBuf
= (nDigit
+ '0' );
828 while ( nValue
> 0 );
830 /* copy the values in the right direction into the destination buffer */
838 while ( pBuf
!= aBuf
);
844 /* ----------------------------------------------------------------------- */
846 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfUInt64
)( IMPL_RTL_STRCODE
* pStr
,
851 sal_Char aBuf
[RTL_STR_MAX_VALUEOFUINT64
];
852 sal_Char
* pBuf
= aBuf
;
856 /* Radix must be valid */
857 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
862 /* create a recursive buffer with all values, except the last one */
865 sal_Char nDigit
= (sal_Char
)(nValue
% nRadix
);
868 *pBuf
= (nDigit
-10) + 'a';
870 *pBuf
= (nDigit
+ '0' );
873 while ( nValue
> 0 );
875 /* copy the values in the right direction into the destination buffer */
883 while ( pBuf
!= aBuf
);
889 /* ----------------------------------------------------------------------- */
891 sal_Bool SAL_CALL
IMPL_RTL_STRNAME( toBoolean
)( const IMPL_RTL_STRCODE
* pStr
)
897 if ( (*pStr
== 'T') || (*pStr
== 't') )
900 if ( (*pStr
== 'R') || (*pStr
== 'r') )
903 if ( (*pStr
== 'U') || (*pStr
== 'u') )
906 if ( (*pStr
== 'E') || (*pStr
== 'e') )
915 /* ----------------------------------------------------------------------- */
917 template <typename T
> static inline T
IMPL_RTL_STRNAME( toInt
)( const IMPL_RTL_STRCODE
* pStr
,
920 BOOST_STATIC_ASSERT(std::numeric_limits
<T
>::is_signed
);
925 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
928 /* Skip whitespaces */
929 while ( *pStr
&& rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr
) ) )
946 nDigit
= rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr
), nRadix
);
963 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( toInt32
)( const IMPL_RTL_STRCODE
* pStr
,
967 return IMPL_RTL_STRNAME( toInt
)<sal_Int32
>(pStr
, nRadix
);
970 sal_Int64 SAL_CALL
IMPL_RTL_STRNAME( toInt64
)( const IMPL_RTL_STRCODE
* pStr
,
974 return IMPL_RTL_STRNAME( toInt
)<sal_Int64
>(pStr
, nRadix
);
977 /* ----------------------------------------------------------------------- */
979 sal_uInt64 SAL_CALL
IMPL_RTL_STRNAME( toUInt64
)( const IMPL_RTL_STRCODE
* pStr
,
986 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
989 /* Skip whitespaces */
990 while ( *pStr
&& rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr
) ) )
993 // skip optional explicit sign
997 const sal_uInt64 nDiv
= SAL_MAX_UINT64
/nRadix
;
998 const sal_Int16 nMod
= SAL_MAX_UINT64
%nRadix
;
1001 nDigit
= rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr
), nRadix
);
1004 if( ( nMod
< nDigit
? nDiv
-1 : nDiv
) < n
)
1016 /* ======================================================================= */
1017 /* Internal String-Class help functions */
1018 /* ======================================================================= */
1020 static IMPL_RTL_STRINGDATA
* IMPL_RTL_STRINGNAME( ImplAlloc
)( sal_Int32 nLen
)
1022 IMPL_RTL_STRINGDATA
* pData
1023 = (sal::static_int_cast
< sal_uInt32
>(nLen
)
1024 <= ((SAL_MAX_UINT32
- sizeof (IMPL_RTL_STRINGDATA
))
1025 / sizeof (IMPL_RTL_STRCODE
)))
1026 ? (IMPL_RTL_STRINGDATA
*) rtl_allocateMemory(
1027 sizeof (IMPL_RTL_STRINGDATA
) + nLen
* sizeof (IMPL_RTL_STRCODE
))
1029 if (pData
!= NULL
) {
1030 pData
->refCount
= 1;
1031 pData
->length
= nLen
;
1032 pData
->buffer
[nLen
] = 0;
1037 /* ----------------------------------------------------------------------- */
1039 static IMPL_RTL_STRCODE
* IMPL_RTL_STRINGNAME( ImplNewCopy
)( IMPL_RTL_STRINGDATA
** ppThis
,
1040 IMPL_RTL_STRINGDATA
* pStr
,
1043 IMPL_RTL_STRCODE
* pDest
;
1044 const IMPL_RTL_STRCODE
* pSrc
;
1045 IMPL_RTL_STRINGDATA
* pData
= IMPL_RTL_STRINGNAME( ImplAlloc
)( pStr
->length
);
1046 OSL_ASSERT(pData
!= NULL
);
1048 pDest
= pData
->buffer
;
1049 pSrc
= pStr
->buffer
;
1050 while ( nCount
> 0 )
1060 RTL_LOG_STRING_NEW( pData
);
1064 /* ======================================================================= */
1065 /* String-Class functions */
1066 /* ======================================================================= */
1068 #define IMPL_RTL_AQUIRE( pThis ) \
1070 if (!SAL_STRING_IS_STATIC (pThis)) \
1071 osl_atomic_increment( &((pThis)->refCount) ); \
1074 /* ----------------------------------------------------------------------- */
1076 void SAL_CALL
IMPL_RTL_STRINGNAME( acquire
)( IMPL_RTL_STRINGDATA
* pThis
)
1077 SAL_THROW_EXTERN_C()
1079 IMPL_RTL_AQUIRE( pThis
);
1082 /* ----------------------------------------------------------------------- */
1084 void SAL_CALL
IMPL_RTL_STRINGNAME( release
)( IMPL_RTL_STRINGDATA
* pThis
)
1085 SAL_THROW_EXTERN_C()
1087 if (SAL_STRING_IS_STATIC (pThis
))
1090 /* OString doesn't have an 'intern' */
1091 #ifdef IMPL_RTL_INTERN
1092 if (SAL_STRING_IS_INTERN (pThis
))
1094 internRelease (pThis
);
1099 if ( !osl_atomic_decrement( &(pThis
->refCount
) ) )
1101 RTL_LOG_STRING_DELETE( pThis
);
1102 rtl_freeMemory( pThis
);
1106 /* ----------------------------------------------------------------------- */
1108 void SAL_CALL
IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA
** ppThis
)
1109 SAL_THROW_EXTERN_C()
1112 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1114 *ppThis
= (IMPL_RTL_STRINGDATA
*) (&IMPL_RTL_EMPTYSTRING
);
1117 /* ----------------------------------------------------------------------- */
1119 IMPL_RTL_STRINGDATA
* SAL_CALL
IMPL_RTL_STRINGNAME( alloc
)( sal_Int32 nLen
)
1120 SAL_THROW_EXTERN_C()
1125 return IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1128 /* ----------------------------------------------------------------------- */
1130 void SAL_CALL
IMPL_RTL_STRINGNAME( new_WithLength
)( IMPL_RTL_STRINGDATA
** ppThis
, sal_Int32 nLen
)
1131 SAL_THROW_EXTERN_C()
1134 IMPL_RTL_STRINGNAME( new )( ppThis
);
1138 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1140 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1141 OSL_ASSERT(*ppThis
!= NULL
);
1142 (*ppThis
)->length
= 0;
1144 IMPL_RTL_STRCODE
* pTempStr
= (*ppThis
)->buffer
;
1145 memset(pTempStr
, 0, nLen
*sizeof(IMPL_RTL_STRCODE
));
1149 /* ----------------------------------------------------------------------- */
1151 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromString
)( IMPL_RTL_STRINGDATA
** ppThis
,
1152 const IMPL_RTL_STRINGDATA
* pStr
)
1153 SAL_THROW_EXTERN_C()
1155 IMPL_RTL_STRINGDATA
* pOrg
;
1157 if ( !pStr
->length
)
1159 IMPL_RTL_STRINGNAME( new )( ppThis
);
1164 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( pStr
->length
);
1165 OSL_ASSERT(*ppThis
!= NULL
);
1166 rtl_str_ImplCopy( (*ppThis
)->buffer
, pStr
->buffer
, pStr
->length
);
1167 RTL_LOG_STRING_NEW( *ppThis
);
1169 /* must be done last, if pStr == *ppThis */
1171 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1174 /* ----------------------------------------------------------------------- */
1176 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromStr
)( IMPL_RTL_STRINGDATA
** ppThis
,
1177 const IMPL_RTL_STRCODE
* pCharStr
)
1178 SAL_THROW_EXTERN_C()
1180 IMPL_RTL_STRCODE
* pBuffer
;
1181 IMPL_RTL_STRINGDATA
* pOrg
;
1186 const IMPL_RTL_STRCODE
* pTempStr
= pCharStr
;
1189 nLen
= pTempStr
-pCharStr
;
1196 IMPL_RTL_STRINGNAME( new )( ppThis
);
1201 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1202 OSL_ASSERT(*ppThis
!= NULL
);
1203 pBuffer
= (*ppThis
)->buffer
;
1206 *pBuffer
= *pCharStr
;
1210 while ( *pCharStr
);
1212 RTL_LOG_STRING_NEW( *ppThis
);
1214 /* must be done last, if pCharStr == *ppThis */
1216 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1219 /* ----------------------------------------------------------------------- */
1221 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromStr_WithLength
)( IMPL_RTL_STRINGDATA
** ppThis
,
1222 const IMPL_RTL_STRCODE
* pCharStr
,
1224 SAL_THROW_EXTERN_C()
1226 IMPL_RTL_STRINGDATA
* pOrg
;
1228 if ( !pCharStr
|| (nLen
<= 0) )
1230 IMPL_RTL_STRINGNAME( new )( ppThis
);
1235 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1236 OSL_ASSERT(*ppThis
!= NULL
);
1237 rtl_str_ImplCopy( (*ppThis
)->buffer
, pCharStr
, nLen
);
1239 RTL_LOG_STRING_NEW( *ppThis
);
1241 /* must be done last, if pCharStr == *ppThis */
1243 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1246 /* ----------------------------------------------------------------------- */
1248 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromSubString
)( IMPL_RTL_STRINGDATA
** ppThis
,
1249 const IMPL_RTL_STRINGDATA
* pFrom
,
1250 sal_Int32 beginIndex
,
1252 SAL_THROW_EXTERN_C()
1254 if ( beginIndex
== 0 && count
== pFrom
->length
)
1256 IMPL_RTL_STRINGNAME( assign
)( ppThis
, const_cast< IMPL_RTL_STRINGDATA
* >( pFrom
) );
1259 if ( count
< 0 || beginIndex
< 0 || beginIndex
+ count
> pFrom
->length
)
1261 assert(false); // fail fast at least in debug builds
1262 IMPL_RTL_STRINGNAME( newFromLiteral
)( ppThis
, "!!br0ken!!", 10, 0 );
1266 IMPL_RTL_STRINGNAME( newFromStr_WithLength
)( ppThis
, pFrom
->buffer
+ beginIndex
, count
);
1269 /* ----------------------------------------------------------------------- */
1271 // Used when creating from string literals.
1272 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromLiteral
)( IMPL_RTL_STRINGDATA
** ppThis
,
1273 const sal_Char
* pCharStr
,
1275 sal_Int32 allocExtra
)
1276 SAL_THROW_EXTERN_C()
1278 if ( nLen
+ allocExtra
== 0 )
1280 IMPL_RTL_STRINGNAME( new )( ppThis
);
1285 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1287 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
+ allocExtra
);
1288 assert( *ppThis
!= NULL
);
1291 (*ppThis
)->length
= nLen
; // fix after possible allocExtra != 0
1292 (*ppThis
)->buffer
[nLen
] = 0;
1293 IMPL_RTL_STRCODE
* pBuffer
= (*ppThis
)->buffer
;
1295 for( nCount
= nLen
; nCount
> 0; --nCount
)
1297 /* Check ASCII range */
1298 SAL_WARN_IF( ((unsigned char)*pCharStr
) > 127, "rtl.string",
1299 "rtl_uString_newFromLiteral - Found char > 127" );
1300 SAL_WARN_IF( ((unsigned char)*pCharStr
) == '\0', "rtl.string",
1301 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1303 *pBuffer
= *pCharStr
;
1309 RTL_LOG_STRING_NEW( *ppThis
);
1312 /* ----------------------------------------------------------------------- */
1314 void SAL_CALL
IMPL_RTL_STRINGNAME( assign
)( IMPL_RTL_STRINGDATA
** ppThis
,
1315 IMPL_RTL_STRINGDATA
* pStr
)
1316 SAL_THROW_EXTERN_C()
1318 /* must be done at first, if pStr == *ppThis */
1319 IMPL_RTL_AQUIRE( pStr
);
1322 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1327 /* ----------------------------------------------------------------------- */
1329 sal_Int32 SAL_CALL
IMPL_RTL_STRINGNAME( getLength
)( const IMPL_RTL_STRINGDATA
* pThis
)
1330 SAL_THROW_EXTERN_C()
1332 return pThis
->length
;
1335 /* ----------------------------------------------------------------------- */
1337 IMPL_RTL_STRCODE
* SAL_CALL
IMPL_RTL_STRINGNAME( getStr
)( IMPL_RTL_STRINGDATA
* pThis
)
1338 SAL_THROW_EXTERN_C()
1340 return pThis
->buffer
;
1343 /* ----------------------------------------------------------------------- */
1345 void SAL_CALL
IMPL_RTL_STRINGNAME( newConcat
)( IMPL_RTL_STRINGDATA
** ppThis
,
1346 IMPL_RTL_STRINGDATA
* pLeft
,
1347 IMPL_RTL_STRINGDATA
* pRight
)
1348 SAL_THROW_EXTERN_C()
1350 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1352 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1353 if ( !pRight
|| !pRight
->length
)
1356 IMPL_RTL_AQUIRE( pLeft
);
1358 else if ( !pLeft
|| !pLeft
->length
)
1361 IMPL_RTL_AQUIRE( pRight
);
1365 IMPL_RTL_STRINGDATA
* pTempStr
= IMPL_RTL_STRINGNAME( ImplAlloc
)( pLeft
->length
+ pRight
->length
);
1366 OSL_ASSERT(pTempStr
!= NULL
);
1367 rtl_str_ImplCopy( pTempStr
->buffer
, pLeft
->buffer
, pLeft
->length
);
1368 rtl_str_ImplCopy( pTempStr
->buffer
+pLeft
->length
, pRight
->buffer
, pRight
->length
);
1371 RTL_LOG_STRING_NEW( *ppThis
);
1374 /* must be done last, if left or right == *ppThis */
1376 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1379 /* ----------------------------------------------------------------------- */
1381 void SAL_CALL
IMPL_RTL_STRINGNAME( ensureCapacity
)( IMPL_RTL_STRINGDATA
** ppThis
,
1383 SAL_THROW_EXTERN_C()
1385 IMPL_RTL_STRINGDATA
* const pOrg
= *ppThis
;
1386 if ( pOrg
->refCount
== 1 && pOrg
->length
>= size
)
1388 assert( pOrg
->length
<= size
); // do not truncate
1389 IMPL_RTL_STRINGDATA
* pTempStr
= IMPL_RTL_STRINGNAME( ImplAlloc
)( size
);
1390 rtl_str_ImplCopy( pTempStr
->buffer
, pOrg
->buffer
, pOrg
->length
);
1391 // right now the length is still the same as of the original
1392 pTempStr
->length
= pOrg
->length
;
1393 pTempStr
->buffer
[ pOrg
->length
] = '\0';
1395 RTL_LOG_STRING_NEW( *ppThis
);
1397 /* must be done last, if pStr == *ppThis */
1399 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1402 /* ----------------------------------------------------------------------- */
1404 void SAL_CALL
IMPL_RTL_STRINGNAME( newReplaceStrAt
)( IMPL_RTL_STRINGDATA
** ppThis
,
1405 IMPL_RTL_STRINGDATA
* pStr
,
1408 IMPL_RTL_STRINGDATA
* pNewSubStr
)
1409 SAL_THROW_EXTERN_C()
1412 if ( nIndex
>= pStr
->length
)
1414 /* newConcat test, if pNewSubStr is 0 */
1415 IMPL_RTL_STRINGNAME( newConcat
)( ppThis
, pStr
, pNewSubStr
);
1419 /* negativ index? */
1426 /* not more than the String length could be deleted */
1427 if ( nCount
>= pStr
->length
-nIndex
)
1429 nCount
= pStr
->length
-nIndex
;
1431 /* Assign of NewSubStr? */
1432 if ( !nIndex
&& (nCount
>= pStr
->length
) )
1435 IMPL_RTL_STRINGNAME( new )( ppThis
);
1437 IMPL_RTL_STRINGNAME( assign
)( ppThis
, pNewSubStr
);
1442 /* Assign of Str? */
1443 if ( !nCount
&& (!pNewSubStr
|| !pNewSubStr
->length
) )
1445 IMPL_RTL_STRINGNAME( assign
)( ppThis
, pStr
);
1449 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1450 IMPL_RTL_STRCODE
* pBuffer
;
1453 /* Calculate length of the new string */
1454 nNewLen
= pStr
->length
-nCount
;
1456 nNewLen
+= pNewSubStr
->length
;
1458 /* Alloc New Buffer */
1459 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nNewLen
);
1460 OSL_ASSERT(*ppThis
!= NULL
);
1461 pBuffer
= (*ppThis
)->buffer
;
1464 rtl_str_ImplCopy( pBuffer
, pStr
->buffer
, nIndex
);
1467 if ( pNewSubStr
&& pNewSubStr
->length
)
1469 rtl_str_ImplCopy( pBuffer
, pNewSubStr
->buffer
, pNewSubStr
->length
);
1470 pBuffer
+= pNewSubStr
->length
;
1472 rtl_str_ImplCopy( pBuffer
, pStr
->buffer
+nIndex
+nCount
, pStr
->length
-nIndex
-nCount
);
1474 RTL_LOG_STRING_NEW( *ppThis
);
1475 /* must be done last, if pStr or pNewSubStr == *ppThis */
1477 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1480 /* ----------------------------------------------------------------------- */
1482 void SAL_CALL
IMPL_RTL_STRINGNAME( newReplace
)( IMPL_RTL_STRINGDATA
** ppThis
,
1483 IMPL_RTL_STRINGDATA
* pStr
,
1484 IMPL_RTL_STRCODE cOld
,
1485 IMPL_RTL_STRCODE cNew
)
1486 SAL_THROW_EXTERN_C()
1488 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1490 sal_Int32 nLen
= pStr
->length
;
1491 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1495 if ( *pCharStr
== cOld
)
1498 IMPL_RTL_STRCODE
* pNewCharStr
= IMPL_RTL_STRINGNAME( ImplNewCopy
)( ppThis
, pStr
, pCharStr
-pStr
->buffer
);
1500 /* replace/copy rest of the string */
1503 *pNewCharStr
= cNew
;
1510 if ( *pCharStr
== cOld
)
1511 *pNewCharStr
= cNew
;
1513 *pNewCharStr
= *pCharStr
;
1532 IMPL_RTL_AQUIRE( pStr
);
1535 RTL_LOG_STRING_NEW( *ppThis
);
1536 /* must be done last, if pStr == *ppThis */
1538 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1541 /* ----------------------------------------------------------------------- */
1543 void SAL_CALL
IMPL_RTL_STRINGNAME( newToAsciiLowerCase
)( IMPL_RTL_STRINGDATA
** ppThis
,
1544 IMPL_RTL_STRINGDATA
* pStr
)
1545 SAL_THROW_EXTERN_C()
1547 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1549 sal_Int32 nLen
= pStr
->length
;
1550 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1554 /* Between A-Z (65-90), than to lowercase (+32) */
1555 if ( (*pCharStr
>= 65) && (*pCharStr
<= 90) )
1558 IMPL_RTL_STRCODE
* pNewCharStr
= IMPL_RTL_STRINGNAME( ImplNewCopy
)( ppThis
, pStr
, pCharStr
-pStr
->buffer
);
1560 /* replace/copy rest of the string */
1563 /* to lowercase (+32) */
1564 *pNewCharStr
= *pCharStr
+32;
1571 /* Between A-Z (65-90), than to lowercase (+32) */
1572 if ( (*pCharStr
>= 65) && (*pCharStr
<= 90) )
1573 *pNewCharStr
= *pCharStr
+32;
1575 *pNewCharStr
= *pCharStr
;
1594 IMPL_RTL_AQUIRE( pStr
);
1597 RTL_LOG_STRING_NEW( *ppThis
);
1598 /* must be done last, if pStr == *ppThis */
1600 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1603 /* ----------------------------------------------------------------------- */
1605 void SAL_CALL
IMPL_RTL_STRINGNAME( newToAsciiUpperCase
)( IMPL_RTL_STRINGDATA
** ppThis
,
1606 IMPL_RTL_STRINGDATA
* pStr
)
1607 SAL_THROW_EXTERN_C()
1609 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1611 sal_Int32 nLen
= pStr
->length
;
1612 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1616 /* Between a-z (97-122), than to uppercase (-32) */
1617 if ( (*pCharStr
>= 97) && (*pCharStr
<= 122) )
1620 IMPL_RTL_STRCODE
* pNewCharStr
= IMPL_RTL_STRINGNAME( ImplNewCopy
)( ppThis
, pStr
, pCharStr
-pStr
->buffer
);
1622 /* replace/copy rest of the string */
1625 /* to uppercase (-32) */
1626 *pNewCharStr
= *pCharStr
-32;
1633 /* Between a-z (97-122), than to uppercase (-32) */
1634 if ( (*pCharStr
>= 97) && (*pCharStr
<= 122) )
1635 *pNewCharStr
= *pCharStr
-32;
1637 *pNewCharStr
= *pCharStr
;
1656 IMPL_RTL_AQUIRE( pStr
);
1659 RTL_LOG_STRING_NEW( *ppThis
);
1660 /* must be done last, if pStr == *ppThis */
1662 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1665 /* ----------------------------------------------------------------------- */
1667 void SAL_CALL
IMPL_RTL_STRINGNAME( newTrim
)( IMPL_RTL_STRINGDATA
** ppThis
,
1668 IMPL_RTL_STRINGDATA
* pStr
)
1669 SAL_THROW_EXTERN_C()
1671 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1672 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1673 sal_Int32 nPreSpaces
= 0;
1674 sal_Int32 nPostSpaces
= 0;
1675 sal_Int32 nLen
= pStr
->length
;
1676 sal_Int32 nIndex
= nLen
-1;
1678 while ( (nPreSpaces
< nLen
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr
+nPreSpaces
)) ) )
1681 while ( (nIndex
> nPreSpaces
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr
+nIndex
)) ) )
1687 if ( !nPreSpaces
&& !nPostSpaces
)
1690 IMPL_RTL_AQUIRE( pStr
);
1694 nLen
-= nPostSpaces
+nPreSpaces
;
1695 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1696 OSL_ASSERT(*ppThis
!= NULL
);
1698 rtl_str_ImplCopy( (*ppThis
)->buffer
, pStr
->buffer
+nPreSpaces
, nLen
);
1701 RTL_LOG_STRING_NEW( *ppThis
);
1702 /* must be done last, if pStr == *ppThis */
1704 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1707 /* ----------------------------------------------------------------------- */
1709 sal_Int32 SAL_CALL
IMPL_RTL_STRINGNAME( getToken
)( IMPL_RTL_STRINGDATA
** ppThis
,
1710 IMPL_RTL_STRINGDATA
* pStr
,
1712 IMPL_RTL_STRCODE cTok
,
1714 SAL_THROW_EXTERN_C()
1716 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1717 const IMPL_RTL_STRCODE
* pCharStrStart
;
1718 const IMPL_RTL_STRCODE
* pOrgCharStr
;
1719 sal_Int32 nLen
= pStr
->length
-nIndex
;
1720 sal_Int32 nTokCount
= 0;
1722 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1728 pOrgCharStr
= pCharStr
;
1729 pCharStrStart
= pCharStr
;
1732 if ( *pCharStr
== cTok
)
1736 if ( nTokCount
== nToken
)
1737 pCharStrStart
= pCharStr
+1;
1740 if ( nTokCount
> nToken
)
1749 if ( (nToken
< 0) || (nTokCount
< nToken
) || (pCharStr
== pCharStrStart
) )
1751 IMPL_RTL_STRINGNAME( new )( ppThis
);
1752 if( (nToken
< 0) || (nTokCount
< nToken
) )
1755 return nIndex
+(pCharStr
-pOrgCharStr
)+1;
1760 IMPL_RTL_STRINGNAME( newFromStr_WithLength
)( ppThis
, pCharStrStart
, pCharStr
-pCharStrStart
);
1762 return nIndex
+(pCharStr
-pOrgCharStr
)+1;
1768 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */