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 /* ======================================================================= */
29 #include <sal/log.hxx>
30 #include <rtl/character.hxx>
31 #include <boost/static_assert.hpp>
34 inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
35 const IMPL_RTL_STRCODE* pSrc,
48 #define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \
50 IMPL_RTL_STRCODE* __mm_pDest = _pDest; \
51 const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \
52 sal_Int32 __mm_nCount = _nCount; \
53 while ( __mm_nCount > 0 ) \
55 *__mm_pDest = *__mm_pSrc; \
62 /* ======================================================================= */
63 /* C-String functions which could be used without the String-Class */
64 /* ======================================================================= */
66 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( getLength
)( const IMPL_RTL_STRCODE
* pStr
)
69 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
75 /* ----------------------------------------------------------------------- */
77 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compare
)( const IMPL_RTL_STRCODE
* pStr1
,
78 const IMPL_RTL_STRCODE
* pStr2
)
82 while ( ((nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE(*pStr1
)))-
83 ((sal_Int32
)(IMPL_RTL_USTRCODE(*pStr2
)))) == 0) &&
93 /* ----------------------------------------------------------------------- */
95 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compare_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
97 const IMPL_RTL_STRCODE
* pStr2
,
101 sal_Int32 nRet
= nStr1Len
- nStr2Len
;
102 int nCount
= (nRet
<= 0) ? nStr1Len
: nStr2Len
;
106 while( (--nCount
>= 0) && (*++pStr1
== *++pStr2
) ) ;
109 nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr1
)))
110 - ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr2
)));
115 /* ----------------------------------------------------------------------- */
117 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( shortenedCompare_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
119 const IMPL_RTL_STRCODE
* pStr2
,
121 sal_Int32 nShortenedLength
)
124 const IMPL_RTL_STRCODE
* pStr1End
= pStr1
+ nStr1Len
;
125 const IMPL_RTL_STRCODE
* pStr2End
= pStr2
+ nStr2Len
;
127 while ( (nShortenedLength
> 0) &&
128 (pStr1
< pStr1End
) && (pStr2
< pStr2End
) )
130 nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr1
)))-
131 ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr2
)));
140 if ( nShortenedLength
<= 0 )
142 return nStr1Len
- nStr2Len
;
145 /* ----------------------------------------------------------------------- */
147 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( reverseCompare_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
149 const IMPL_RTL_STRCODE
* pStr2
,
153 const IMPL_RTL_STRCODE
* pStr1Run
= pStr1
+nStr1Len
;
154 const IMPL_RTL_STRCODE
* pStr2Run
= pStr2
+nStr2Len
;
156 while ( (pStr1
< pStr1Run
) && (pStr2
< pStr2Run
) )
160 nRet
= ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr1Run
)))-
161 ((sal_Int32
)(IMPL_RTL_USTRCODE( *pStr2Run
)));
166 return nStr1Len
- nStr2Len
;
169 /* ----------------------------------------------------------------------- */
171 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compareIgnoreAsciiCase
)( const IMPL_RTL_STRCODE
* pStr1
,
172 const IMPL_RTL_STRCODE
* pStr2
)
178 c1
= IMPL_RTL_USTRCODE(*pStr1
);
179 sal_Int32 nRet
= rtl::compareIgnoreAsciiCase(
180 c1
, IMPL_RTL_USTRCODE(*pStr2
));
192 /* ----------------------------------------------------------------------- */
194 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
196 const IMPL_RTL_STRCODE
* pStr2
,
200 const IMPL_RTL_STRCODE
* pStr1End
= pStr1
+ nStr1Len
;
201 const IMPL_RTL_STRCODE
* pStr2End
= pStr2
+ nStr2Len
;
202 while ( (pStr1
< pStr1End
) && (pStr2
< pStr2End
) )
204 sal_Int32 nRet
= rtl::compareIgnoreAsciiCase(
205 IMPL_RTL_USTRCODE(*pStr1
), IMPL_RTL_USTRCODE(*pStr2
));
213 return nStr1Len
- nStr2Len
;
216 /* ----------------------------------------------------------------------- */
218 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength
)( const IMPL_RTL_STRCODE
* pStr1
,
220 const IMPL_RTL_STRCODE
* pStr2
,
222 sal_Int32 nShortenedLength
)
225 const IMPL_RTL_STRCODE
* pStr1End
= pStr1
+ nStr1Len
;
226 const IMPL_RTL_STRCODE
* pStr2End
= pStr2
+ nStr2Len
;
227 while ( (nShortenedLength
> 0) &&
228 (pStr1
< pStr1End
) && (pStr2
< pStr2End
) )
230 sal_Int32 nRet
= rtl::compareIgnoreAsciiCase(
231 IMPL_RTL_USTRCODE(*pStr1
), IMPL_RTL_USTRCODE(*pStr2
));
240 if ( nShortenedLength
<= 0 )
242 return nStr1Len
- nStr2Len
;
245 /* ----------------------------------------------------------------------- */
247 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( hashCode
)( const IMPL_RTL_STRCODE
* pStr
)
250 return IMPL_RTL_STRNAME( hashCode_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
) );
253 /* ----------------------------------------------------------------------- */
255 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( hashCode_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
259 sal_uInt32 h
= static_cast<sal_uInt32
>(nLen
);
262 h
= (h
*37U) + IMPL_RTL_USTRCODE( *pStr
);
266 return static_cast<sal_Int32
>(h
);
269 /* ----------------------------------------------------------------------- */
271 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfChar
)( const IMPL_RTL_STRCODE
* pStr
,
275 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
278 if ( *pTempStr
== c
)
279 return pTempStr
-pStr
;
287 /* ----------------------------------------------------------------------- */
289 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfChar_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
294 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
297 if ( *pTempStr
== c
)
298 return pTempStr
-pStr
;
307 /* ----------------------------------------------------------------------- */
309 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfChar
)( const IMPL_RTL_STRCODE
* pStr
,
313 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
), c
);
316 /* ----------------------------------------------------------------------- */
318 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfChar_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
336 /* ----------------------------------------------------------------------- */
338 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfStr
)( const IMPL_RTL_STRCODE
* pStr
,
339 const IMPL_RTL_STRCODE
* pSubStr
)
342 return IMPL_RTL_STRNAME( indexOfStr_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
),
343 pSubStr
, IMPL_RTL_STRNAME( getLength
)( pSubStr
) );
346 /* ----------------------------------------------------------------------- */
348 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( indexOfStr_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
350 const IMPL_RTL_STRCODE
* pSubStr
,
354 /* faster search for a single character */
357 /* an empty SubString is always not foundable */
360 IMPL_RTL_STRCODE c
= *pSubStr
;
361 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
362 while ( nStrLen
> 0 )
364 if ( *pTempStr
== c
)
365 return pTempStr
-pStr
;
374 const IMPL_RTL_STRCODE
* pTempStr
= pStr
;
375 while ( nStrLen
> 0 )
377 if ( *pTempStr
== *pSubStr
)
379 /* Compare SubString */
380 if ( nSubLen
<= nStrLen
)
382 const IMPL_RTL_STRCODE
* pTempStr1
= pTempStr
;
383 const IMPL_RTL_STRCODE
* pTempStr2
= pSubStr
;
384 sal_Int32 nTempLen
= nSubLen
;
387 if ( *pTempStr1
!= *pTempStr2
)
396 return pTempStr
-pStr
;
410 /* ----------------------------------------------------------------------- */
412 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfStr
)( const IMPL_RTL_STRCODE
* pStr
,
413 const IMPL_RTL_STRCODE
* pSubStr
)
416 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
),
417 pSubStr
, IMPL_RTL_STRNAME( getLength
)( pSubStr
) );
420 /* ----------------------------------------------------------------------- */
422 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( lastIndexOfStr_WithLength
)( const IMPL_RTL_STRCODE
* pStr
,
424 const IMPL_RTL_STRCODE
* pSubStr
,
428 /* faster search for a single character */
431 /* an empty SubString is always not foundable */
434 IMPL_RTL_STRCODE c
= *pSubStr
;
436 while ( nStrLen
> 0 )
451 while ( nStrLen
>= 0 )
453 const IMPL_RTL_STRCODE
* pTempStr1
= pStr
;
454 const IMPL_RTL_STRCODE
* pTempStr2
= pSubStr
;
455 sal_Int32 nTempLen
= nSubLen
;
458 if ( *pTempStr1
!= *pTempStr2
)
477 /* ----------------------------------------------------------------------- */
479 void SAL_CALL
IMPL_RTL_STRNAME( replaceChar
)( IMPL_RTL_STRCODE
* pStr
,
480 IMPL_RTL_STRCODE cOld
,
481 IMPL_RTL_STRCODE cNew
)
493 /* ----------------------------------------------------------------------- */
495 void SAL_CALL
IMPL_RTL_STRNAME( replaceChar_WithLength
)( IMPL_RTL_STRCODE
* pStr
,
497 IMPL_RTL_STRCODE cOld
,
498 IMPL_RTL_STRCODE cNew
)
511 /* ----------------------------------------------------------------------- */
513 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiLowerCase
)( IMPL_RTL_STRCODE
* pStr
)
518 *pStr
= rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr
));
524 /* ----------------------------------------------------------------------- */
526 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength
)( IMPL_RTL_STRCODE
* pStr
,
532 *pStr
= rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr
));
539 /* ----------------------------------------------------------------------- */
541 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiUpperCase
)( IMPL_RTL_STRCODE
* pStr
)
546 *pStr
= rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr
));
552 /* ----------------------------------------------------------------------- */
554 void SAL_CALL
IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength
)( IMPL_RTL_STRCODE
* pStr
,
560 *pStr
= rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr
));
567 /* ----------------------------------------------------------------------- */
569 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( trim
)( IMPL_RTL_STRCODE
* pStr
)
572 return IMPL_RTL_STRNAME( trim_WithLength
)( pStr
, IMPL_RTL_STRNAME( getLength
)( pStr
) );
575 /* ----------------------------------------------------------------------- */
577 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( trim_WithLength
)( IMPL_RTL_STRCODE
* pStr
, sal_Int32 nLen
)
580 sal_Int32 nPreSpaces
= 0;
581 sal_Int32 nPostSpaces
= 0;
582 sal_Int32 nIndex
= nLen
-1;
584 while ( (nPreSpaces
< nLen
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr
+nPreSpaces
)) ) )
587 while ( (nIndex
> nPreSpaces
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr
+nIndex
)) ) )
601 IMPL_RTL_STRCODE
* pNewStr
= pStr
+nPreSpaces
;
619 /* ----------------------------------------------------------------------- */
621 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfBoolean
)( IMPL_RTL_STRCODE
* pStr
, sal_Bool b
)
654 /* ----------------------------------------------------------------------- */
656 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfChar
)( IMPL_RTL_STRCODE
* pStr
,
665 /* ----------------------------------------------------------------------- */
667 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfInt32
)( IMPL_RTL_STRCODE
* pStr
,
672 sal_Char aBuf
[RTL_STR_MAX_VALUEOFINT32
];
673 sal_Char
* pBuf
= aBuf
;
677 /* Radix must be valid */
678 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
681 /* is value negativ */
687 nValue
= n
== SAL_MIN_INT32
? static_cast<sal_uInt32
>(n
) : -n
;
692 /* create a recursive buffer with all values, except the last one */
695 sal_Char nDigit
= (sal_Char
)(nValue
% nRadix
);
698 *pBuf
= (nDigit
-10) + 'a';
700 *pBuf
= (nDigit
+ '0' );
703 while ( nValue
> 0 );
705 /* copy the values in the right direction into the destination buffer */
713 while ( pBuf
!= aBuf
);
719 /* ----------------------------------------------------------------------- */
721 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfInt64
)( IMPL_RTL_STRCODE
* pStr
,
726 sal_Char aBuf
[RTL_STR_MAX_VALUEOFINT64
];
727 sal_Char
* pBuf
= aBuf
;
731 /* Radix must be valid */
732 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
735 /* is value negativ */
741 nValue
= n
== SAL_MIN_INT64
? static_cast<sal_uInt64
>(n
) : -n
;
746 /* create a recursive buffer with all values, except the last one */
749 sal_Char nDigit
= (sal_Char
)(nValue
% nRadix
);
752 *pBuf
= (nDigit
-10) + 'a';
754 *pBuf
= (nDigit
+ '0' );
757 while ( nValue
> 0 );
759 /* copy the values in the right direction into the destination buffer */
767 while ( pBuf
!= aBuf
);
773 /* ----------------------------------------------------------------------- */
775 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( valueOfUInt64
)( IMPL_RTL_STRCODE
* pStr
,
780 sal_Char aBuf
[RTL_STR_MAX_VALUEOFUINT64
];
781 sal_Char
* pBuf
= aBuf
;
785 /* Radix must be valid */
786 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
791 /* create a recursive buffer with all values, except the last one */
794 sal_Char nDigit
= (sal_Char
)(nValue
% nRadix
);
797 *pBuf
= (nDigit
-10) + 'a';
799 *pBuf
= (nDigit
+ '0' );
802 while ( nValue
> 0 );
804 /* copy the values in the right direction into the destination buffer */
812 while ( pBuf
!= aBuf
);
818 /* ----------------------------------------------------------------------- */
820 sal_Bool SAL_CALL
IMPL_RTL_STRNAME( toBoolean
)( const IMPL_RTL_STRCODE
* pStr
)
826 if ( (*pStr
== 'T') || (*pStr
== 't') )
829 if ( (*pStr
== 'R') || (*pStr
== 'r') )
832 if ( (*pStr
== 'U') || (*pStr
== 'u') )
835 if ( (*pStr
== 'E') || (*pStr
== 'e') )
844 /* ----------------------------------------------------------------------- */
846 template<typename T
, typename U
> static inline T
IMPL_RTL_STRNAME( toInt
)( const IMPL_RTL_STRCODE
* pStr
,
849 BOOST_STATIC_ASSERT(std::numeric_limits
<T
>::is_signed
);
854 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
857 /* Skip whitespaces */
858 while ( *pStr
&& rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr
) ) )
877 nDiv
= std::numeric_limits
<T
>::min() / nRadix
;
878 nMod
= std::numeric_limits
<T
>::min() % nRadix
;
879 // Cater for C++03 implementations that round the quotient down
880 // instead of truncating towards zero as mandated by C++11:
891 nDiv
= std::numeric_limits
<T
>::max() / nRadix
;
892 nMod
= std::numeric_limits
<T
>::max() % nRadix
;
897 nDigit
= rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr
), nRadix
);
901 if( static_cast<U
>( nMod
< nDigit
? nDiv
-1 : nDiv
) < n
)
911 return n
== static_cast<U
>(std::numeric_limits
<T
>::min())
912 ? std::numeric_limits
<T
>::min() : -static_cast<T
>(n
);
914 return static_cast<T
>(n
);
918 sal_Int32 SAL_CALL
IMPL_RTL_STRNAME( toInt32
)( const IMPL_RTL_STRCODE
* pStr
,
922 return IMPL_RTL_STRNAME( toInt
)<sal_Int32
, sal_uInt32
>(pStr
, nRadix
);
925 sal_Int64 SAL_CALL
IMPL_RTL_STRNAME( toInt64
)( const IMPL_RTL_STRCODE
* pStr
,
929 return IMPL_RTL_STRNAME( toInt
)<sal_Int64
, sal_uInt64
>(pStr
, nRadix
);
932 /* ----------------------------------------------------------------------- */
934 template <typename T
> static inline T
IMPL_RTL_STRNAME( toUInt
)( const IMPL_RTL_STRCODE
* pStr
,
937 BOOST_STATIC_ASSERT(!std::numeric_limits
<T
>::is_signed
);
941 if ( (nRadix
< RTL_STR_MIN_RADIX
) || (nRadix
> RTL_STR_MAX_RADIX
) )
944 /* Skip whitespaces */
945 while ( *pStr
&& rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr
) ) )
948 // skip optional explicit sign
952 T nDiv
= std::numeric_limits
<T
>::max() / nRadix
;
953 sal_Int16 nMod
= std::numeric_limits
<T
>::max() % nRadix
;
956 nDigit
= rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr
), nRadix
);
959 if( ( nMod
< nDigit
? nDiv
-1 : nDiv
) < n
)
972 sal_uInt32 SAL_CALL
IMPL_RTL_STRNAME( toUInt32
)( const IMPL_RTL_STRCODE
* pStr
,
976 return IMPL_RTL_STRNAME( toUInt
)<sal_uInt32
>(pStr
, nRadix
);
979 sal_uInt64 SAL_CALL
IMPL_RTL_STRNAME( toUInt64
)( const IMPL_RTL_STRCODE
* pStr
,
983 return IMPL_RTL_STRNAME( toUInt
)<sal_uInt64
>(pStr
, nRadix
);
986 /* ======================================================================= */
987 /* Internal String-Class help functions */
988 /* ======================================================================= */
990 static IMPL_RTL_STRINGDATA
* IMPL_RTL_STRINGNAME( ImplAlloc
)( sal_Int32 nLen
)
992 IMPL_RTL_STRINGDATA
* pData
993 = (sal::static_int_cast
< sal_uInt32
>(nLen
)
994 <= ((SAL_MAX_UINT32
- sizeof (IMPL_RTL_STRINGDATA
))
995 / sizeof (IMPL_RTL_STRCODE
)))
996 ? (IMPL_RTL_STRINGDATA
*) rtl_allocateMemory(
997 sizeof (IMPL_RTL_STRINGDATA
) + nLen
* sizeof (IMPL_RTL_STRCODE
))
1000 pData
->refCount
= 1;
1001 pData
->length
= nLen
;
1002 pData
->buffer
[nLen
] = 0;
1007 /* ----------------------------------------------------------------------- */
1009 static IMPL_RTL_STRCODE
* IMPL_RTL_STRINGNAME( ImplNewCopy
)( IMPL_RTL_STRINGDATA
** ppThis
,
1010 IMPL_RTL_STRINGDATA
* pStr
,
1013 IMPL_RTL_STRCODE
* pDest
;
1014 const IMPL_RTL_STRCODE
* pSrc
;
1015 IMPL_RTL_STRINGDATA
* pData
= IMPL_RTL_STRINGNAME( ImplAlloc
)( pStr
->length
);
1016 OSL_ASSERT(pData
!= NULL
);
1018 pDest
= pData
->buffer
;
1019 pSrc
= pStr
->buffer
;
1020 while ( nCount
> 0 )
1030 RTL_LOG_STRING_NEW( pData
);
1034 /* ======================================================================= */
1035 /* String-Class functions */
1036 /* ======================================================================= */
1038 #define IMPL_RTL_AQUIRE( pThis ) \
1040 if (!SAL_STRING_IS_STATIC (pThis)) \
1041 osl_atomic_increment( &((pThis)->refCount) ); \
1044 /* ----------------------------------------------------------------------- */
1046 void SAL_CALL
IMPL_RTL_STRINGNAME( acquire
)( IMPL_RTL_STRINGDATA
* pThis
)
1047 SAL_THROW_EXTERN_C()
1049 IMPL_RTL_AQUIRE( pThis
);
1052 /* ----------------------------------------------------------------------- */
1054 void SAL_CALL
IMPL_RTL_STRINGNAME( release
)( IMPL_RTL_STRINGDATA
* pThis
)
1055 SAL_THROW_EXTERN_C()
1057 if (SAL_STRING_IS_STATIC (pThis
))
1060 /* OString doesn't have an 'intern' */
1061 #ifdef IMPL_RTL_INTERN
1062 if (SAL_STRING_IS_INTERN (pThis
))
1064 internRelease (pThis
);
1069 if ( !osl_atomic_decrement( &(pThis
->refCount
) ) )
1071 RTL_LOG_STRING_DELETE( pThis
);
1072 rtl_freeMemory( pThis
);
1076 /* ----------------------------------------------------------------------- */
1078 void SAL_CALL
IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA
** ppThis
)
1079 SAL_THROW_EXTERN_C()
1082 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1084 *ppThis
= (IMPL_RTL_STRINGDATA
*) (&IMPL_RTL_EMPTYSTRING
);
1087 /* ----------------------------------------------------------------------- */
1089 IMPL_RTL_STRINGDATA
* SAL_CALL
IMPL_RTL_STRINGNAME( alloc
)( sal_Int32 nLen
)
1090 SAL_THROW_EXTERN_C()
1095 return IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1098 /* ----------------------------------------------------------------------- */
1100 void SAL_CALL
IMPL_RTL_STRINGNAME( new_WithLength
)( IMPL_RTL_STRINGDATA
** ppThis
, sal_Int32 nLen
)
1101 SAL_THROW_EXTERN_C()
1104 IMPL_RTL_STRINGNAME( new )( ppThis
);
1108 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1110 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1111 OSL_ASSERT(*ppThis
!= NULL
);
1112 (*ppThis
)->length
= 0;
1114 IMPL_RTL_STRCODE
* pTempStr
= (*ppThis
)->buffer
;
1115 memset(pTempStr
, 0, nLen
*sizeof(IMPL_RTL_STRCODE
));
1119 /* ----------------------------------------------------------------------- */
1121 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromString
)( IMPL_RTL_STRINGDATA
** ppThis
,
1122 const IMPL_RTL_STRINGDATA
* pStr
)
1123 SAL_THROW_EXTERN_C()
1125 IMPL_RTL_STRINGDATA
* pOrg
;
1127 if ( !pStr
->length
)
1129 IMPL_RTL_STRINGNAME( new )( ppThis
);
1134 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( pStr
->length
);
1135 OSL_ASSERT(*ppThis
!= NULL
);
1136 rtl_str_ImplCopy( (*ppThis
)->buffer
, pStr
->buffer
, pStr
->length
);
1137 RTL_LOG_STRING_NEW( *ppThis
);
1139 /* must be done last, if pStr == *ppThis */
1141 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1144 /* ----------------------------------------------------------------------- */
1146 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromStr
)( IMPL_RTL_STRINGDATA
** ppThis
,
1147 const IMPL_RTL_STRCODE
* pCharStr
)
1148 SAL_THROW_EXTERN_C()
1150 IMPL_RTL_STRCODE
* pBuffer
;
1151 IMPL_RTL_STRINGDATA
* pOrg
;
1156 const IMPL_RTL_STRCODE
* pTempStr
= pCharStr
;
1159 nLen
= pTempStr
-pCharStr
;
1166 IMPL_RTL_STRINGNAME( new )( ppThis
);
1171 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1172 OSL_ASSERT(*ppThis
!= NULL
);
1173 pBuffer
= (*ppThis
)->buffer
;
1176 *pBuffer
= *pCharStr
;
1180 while ( *pCharStr
);
1182 RTL_LOG_STRING_NEW( *ppThis
);
1184 /* must be done last, if pCharStr == *ppThis */
1186 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1189 /* ----------------------------------------------------------------------- */
1191 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromStr_WithLength
)( IMPL_RTL_STRINGDATA
** ppThis
,
1192 const IMPL_RTL_STRCODE
* pCharStr
,
1194 SAL_THROW_EXTERN_C()
1196 IMPL_RTL_STRINGDATA
* pOrg
;
1198 if ( !pCharStr
|| (nLen
<= 0) )
1200 IMPL_RTL_STRINGNAME( new )( ppThis
);
1205 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1206 OSL_ASSERT(*ppThis
!= NULL
);
1207 rtl_str_ImplCopy( (*ppThis
)->buffer
, pCharStr
, nLen
);
1209 RTL_LOG_STRING_NEW( *ppThis
);
1211 /* must be done last, if pCharStr == *ppThis */
1213 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1216 /* ----------------------------------------------------------------------- */
1218 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromSubString
)( IMPL_RTL_STRINGDATA
** ppThis
,
1219 const IMPL_RTL_STRINGDATA
* pFrom
,
1220 sal_Int32 beginIndex
,
1222 SAL_THROW_EXTERN_C()
1224 if ( beginIndex
== 0 && count
== pFrom
->length
)
1226 IMPL_RTL_STRINGNAME( assign
)( ppThis
, const_cast< IMPL_RTL_STRINGDATA
* >( pFrom
) );
1229 if ( count
< 0 || beginIndex
< 0 || beginIndex
+ count
> pFrom
->length
)
1231 assert(false); // fail fast at least in debug builds
1232 IMPL_RTL_STRINGNAME( newFromLiteral
)( ppThis
, "!!br0ken!!", 10, 0 );
1236 IMPL_RTL_STRINGNAME( newFromStr_WithLength
)( ppThis
, pFrom
->buffer
+ beginIndex
, count
);
1239 /* ----------------------------------------------------------------------- */
1241 // Used when creating from string literals.
1242 void SAL_CALL
IMPL_RTL_STRINGNAME( newFromLiteral
)( IMPL_RTL_STRINGDATA
** ppThis
,
1243 const sal_Char
* pCharStr
,
1245 sal_Int32 allocExtra
)
1246 SAL_THROW_EXTERN_C()
1248 if ( nLen
+ allocExtra
== 0 )
1250 IMPL_RTL_STRINGNAME( new )( ppThis
);
1255 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1257 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
+ allocExtra
);
1258 assert( *ppThis
!= NULL
);
1261 (*ppThis
)->length
= nLen
; // fix after possible allocExtra != 0
1262 (*ppThis
)->buffer
[nLen
] = 0;
1263 IMPL_RTL_STRCODE
* pBuffer
= (*ppThis
)->buffer
;
1265 for( nCount
= nLen
; nCount
> 0; --nCount
)
1267 /* Check ASCII range */
1268 SAL_WARN_IF( ((unsigned char)*pCharStr
) > 127, "rtl.string",
1269 "rtl_uString_newFromLiteral - Found char > 127" );
1270 SAL_WARN_IF( ((unsigned char)*pCharStr
) == '\0', "rtl.string",
1271 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1273 *pBuffer
= *pCharStr
;
1279 RTL_LOG_STRING_NEW( *ppThis
);
1282 /* ----------------------------------------------------------------------- */
1284 void SAL_CALL
IMPL_RTL_STRINGNAME( assign
)( IMPL_RTL_STRINGDATA
** ppThis
,
1285 IMPL_RTL_STRINGDATA
* pStr
)
1286 SAL_THROW_EXTERN_C()
1288 /* must be done at first, if pStr == *ppThis */
1289 IMPL_RTL_AQUIRE( pStr
);
1292 IMPL_RTL_STRINGNAME( release
)( *ppThis
);
1297 /* ----------------------------------------------------------------------- */
1299 sal_Int32 SAL_CALL
IMPL_RTL_STRINGNAME( getLength
)( const IMPL_RTL_STRINGDATA
* pThis
)
1300 SAL_THROW_EXTERN_C()
1302 return pThis
->length
;
1305 /* ----------------------------------------------------------------------- */
1307 IMPL_RTL_STRCODE
* SAL_CALL
IMPL_RTL_STRINGNAME( getStr
)( IMPL_RTL_STRINGDATA
* pThis
)
1308 SAL_THROW_EXTERN_C()
1310 return pThis
->buffer
;
1313 /* ----------------------------------------------------------------------- */
1315 void SAL_CALL
IMPL_RTL_STRINGNAME( newConcat
)( IMPL_RTL_STRINGDATA
** ppThis
,
1316 IMPL_RTL_STRINGDATA
* pLeft
,
1317 IMPL_RTL_STRINGDATA
* pRight
)
1318 SAL_THROW_EXTERN_C()
1320 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1322 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1323 if ( !pRight
|| !pRight
->length
)
1326 IMPL_RTL_AQUIRE( pLeft
);
1328 else if ( !pLeft
|| !pLeft
->length
)
1331 IMPL_RTL_AQUIRE( pRight
);
1335 IMPL_RTL_STRINGDATA
* pTempStr
= IMPL_RTL_STRINGNAME( ImplAlloc
)( pLeft
->length
+ pRight
->length
);
1336 OSL_ASSERT(pTempStr
!= NULL
);
1337 rtl_str_ImplCopy( pTempStr
->buffer
, pLeft
->buffer
, pLeft
->length
);
1338 rtl_str_ImplCopy( pTempStr
->buffer
+pLeft
->length
, pRight
->buffer
, pRight
->length
);
1341 RTL_LOG_STRING_NEW( *ppThis
);
1344 /* must be done last, if left or right == *ppThis */
1346 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1349 /* ----------------------------------------------------------------------- */
1351 void SAL_CALL
IMPL_RTL_STRINGNAME( ensureCapacity
)( IMPL_RTL_STRINGDATA
** ppThis
,
1353 SAL_THROW_EXTERN_C()
1355 IMPL_RTL_STRINGDATA
* const pOrg
= *ppThis
;
1356 if ( pOrg
->refCount
== 1 && pOrg
->length
>= size
)
1358 assert( pOrg
->length
<= size
); // do not truncate
1359 IMPL_RTL_STRINGDATA
* pTempStr
= IMPL_RTL_STRINGNAME( ImplAlloc
)( size
);
1360 rtl_str_ImplCopy( pTempStr
->buffer
, pOrg
->buffer
, pOrg
->length
);
1361 // right now the length is still the same as of the original
1362 pTempStr
->length
= pOrg
->length
;
1363 pTempStr
->buffer
[ pOrg
->length
] = '\0';
1365 RTL_LOG_STRING_NEW( *ppThis
);
1367 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1370 /* ----------------------------------------------------------------------- */
1372 void SAL_CALL
IMPL_RTL_STRINGNAME( newReplaceStrAt
)( IMPL_RTL_STRINGDATA
** ppThis
,
1373 IMPL_RTL_STRINGDATA
* pStr
,
1376 IMPL_RTL_STRINGDATA
* pNewSubStr
)
1377 SAL_THROW_EXTERN_C()
1380 if ( nIndex
>= pStr
->length
)
1382 /* newConcat test, if pNewSubStr is 0 */
1383 IMPL_RTL_STRINGNAME( newConcat
)( ppThis
, pStr
, pNewSubStr
);
1387 /* negativ index? */
1394 /* not more than the String length could be deleted */
1395 if ( nCount
>= pStr
->length
-nIndex
)
1397 nCount
= pStr
->length
-nIndex
;
1399 /* Assign of NewSubStr? */
1400 if ( !nIndex
&& (nCount
>= pStr
->length
) )
1403 IMPL_RTL_STRINGNAME( new )( ppThis
);
1405 IMPL_RTL_STRINGNAME( assign
)( ppThis
, pNewSubStr
);
1410 /* Assign of Str? */
1411 if ( !nCount
&& (!pNewSubStr
|| !pNewSubStr
->length
) )
1413 IMPL_RTL_STRINGNAME( assign
)( ppThis
, pStr
);
1417 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1418 IMPL_RTL_STRCODE
* pBuffer
;
1421 /* Calculate length of the new string */
1422 nNewLen
= pStr
->length
-nCount
;
1424 nNewLen
+= pNewSubStr
->length
;
1426 /* Alloc New Buffer */
1427 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nNewLen
);
1428 OSL_ASSERT(*ppThis
!= NULL
);
1429 pBuffer
= (*ppThis
)->buffer
;
1432 rtl_str_ImplCopy( pBuffer
, pStr
->buffer
, nIndex
);
1435 if ( pNewSubStr
&& pNewSubStr
->length
)
1437 rtl_str_ImplCopy( pBuffer
, pNewSubStr
->buffer
, pNewSubStr
->length
);
1438 pBuffer
+= pNewSubStr
->length
;
1440 rtl_str_ImplCopy( pBuffer
, pStr
->buffer
+nIndex
+nCount
, pStr
->length
-nIndex
-nCount
);
1442 RTL_LOG_STRING_NEW( *ppThis
);
1443 /* must be done last, if pStr or pNewSubStr == *ppThis */
1445 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1448 /* ----------------------------------------------------------------------- */
1450 void SAL_CALL
IMPL_RTL_STRINGNAME( newReplace
)( IMPL_RTL_STRINGDATA
** ppThis
,
1451 IMPL_RTL_STRINGDATA
* pStr
,
1452 IMPL_RTL_STRCODE cOld
,
1453 IMPL_RTL_STRCODE cNew
)
1454 SAL_THROW_EXTERN_C()
1456 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1458 sal_Int32 nLen
= pStr
->length
;
1459 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1463 if ( *pCharStr
== cOld
)
1466 IMPL_RTL_STRCODE
* pNewCharStr
= IMPL_RTL_STRINGNAME( ImplNewCopy
)( ppThis
, pStr
, pCharStr
-pStr
->buffer
);
1468 /* replace/copy rest of the string */
1471 *pNewCharStr
= cNew
;
1478 if ( *pCharStr
== cOld
)
1479 *pNewCharStr
= cNew
;
1481 *pNewCharStr
= *pCharStr
;
1500 IMPL_RTL_AQUIRE( pStr
);
1503 RTL_LOG_STRING_NEW( *ppThis
);
1504 /* must be done last, if pStr == *ppThis */
1506 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1509 /* ----------------------------------------------------------------------- */
1511 void SAL_CALL
IMPL_RTL_STRINGNAME( newToAsciiLowerCase
)( IMPL_RTL_STRINGDATA
** ppThis
,
1512 IMPL_RTL_STRINGDATA
* pStr
)
1513 SAL_THROW_EXTERN_C()
1515 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1517 sal_Int32 nLen
= pStr
->length
;
1518 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1522 if ( rtl::isAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr
)) )
1525 IMPL_RTL_STRCODE
* pNewCharStr
= IMPL_RTL_STRINGNAME( ImplNewCopy
)( ppThis
, pStr
, pCharStr
-pStr
->buffer
);
1527 /* replace/copy rest of the string */
1530 *pNewCharStr
= rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr
));
1537 *pNewCharStr
= rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr
));
1556 IMPL_RTL_AQUIRE( pStr
);
1559 RTL_LOG_STRING_NEW( *ppThis
);
1560 /* must be done last, if pStr == *ppThis */
1562 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1565 /* ----------------------------------------------------------------------- */
1567 void SAL_CALL
IMPL_RTL_STRINGNAME( newToAsciiUpperCase
)( IMPL_RTL_STRINGDATA
** ppThis
,
1568 IMPL_RTL_STRINGDATA
* pStr
)
1569 SAL_THROW_EXTERN_C()
1571 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1573 sal_Int32 nLen
= pStr
->length
;
1574 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1578 if ( rtl::isAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr
)) )
1581 IMPL_RTL_STRCODE
* pNewCharStr
= IMPL_RTL_STRINGNAME( ImplNewCopy
)( ppThis
, pStr
, pCharStr
-pStr
->buffer
);
1583 /* replace/copy rest of the string */
1586 *pNewCharStr
= rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr
));
1593 *pNewCharStr
= rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr
));
1612 IMPL_RTL_AQUIRE( pStr
);
1615 RTL_LOG_STRING_NEW( *ppThis
);
1616 /* must be done last, if pStr == *ppThis */
1618 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1621 /* ----------------------------------------------------------------------- */
1623 void SAL_CALL
IMPL_RTL_STRINGNAME( newTrim
)( IMPL_RTL_STRINGDATA
** ppThis
,
1624 IMPL_RTL_STRINGDATA
* pStr
)
1625 SAL_THROW_EXTERN_C()
1627 IMPL_RTL_STRINGDATA
* pOrg
= *ppThis
;
1628 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1629 sal_Int32 nPreSpaces
= 0;
1630 sal_Int32 nPostSpaces
= 0;
1631 sal_Int32 nLen
= pStr
->length
;
1632 sal_Int32 nIndex
= nLen
-1;
1634 while ( (nPreSpaces
< nLen
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr
+nPreSpaces
)) ) )
1637 while ( (nIndex
> nPreSpaces
) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr
+nIndex
)) ) )
1643 if ( !nPreSpaces
&& !nPostSpaces
)
1646 IMPL_RTL_AQUIRE( pStr
);
1650 nLen
-= nPostSpaces
+nPreSpaces
;
1651 *ppThis
= IMPL_RTL_STRINGNAME( ImplAlloc
)( nLen
);
1652 OSL_ASSERT(*ppThis
!= NULL
);
1654 rtl_str_ImplCopy( (*ppThis
)->buffer
, pStr
->buffer
+nPreSpaces
, nLen
);
1657 RTL_LOG_STRING_NEW( *ppThis
);
1658 /* must be done last, if pStr == *ppThis */
1660 IMPL_RTL_STRINGNAME( release
)( pOrg
);
1663 /* ----------------------------------------------------------------------- */
1665 sal_Int32 SAL_CALL
IMPL_RTL_STRINGNAME( getToken
)( IMPL_RTL_STRINGDATA
** ppThis
,
1666 IMPL_RTL_STRINGDATA
* pStr
,
1668 IMPL_RTL_STRCODE cTok
,
1670 SAL_THROW_EXTERN_C()
1672 const IMPL_RTL_STRCODE
* pCharStr
= pStr
->buffer
;
1673 const IMPL_RTL_STRCODE
* pCharStrStart
;
1674 const IMPL_RTL_STRCODE
* pOrgCharStr
;
1675 sal_Int32 nLen
= pStr
->length
-nIndex
;
1676 sal_Int32 nTokCount
= 0;
1678 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1684 pOrgCharStr
= pCharStr
;
1685 pCharStrStart
= pCharStr
;
1688 if ( *pCharStr
== cTok
)
1692 if ( nTokCount
== nToken
)
1693 pCharStrStart
= pCharStr
+1;
1696 if ( nTokCount
> nToken
)
1705 if ( (nToken
< 0) || (nTokCount
< nToken
) || (pCharStr
== pCharStrStart
) )
1707 IMPL_RTL_STRINGNAME( new )( ppThis
);
1708 if( (nToken
< 0) || (nTokCount
< nToken
) )
1711 return nIndex
+(pCharStr
-pOrgCharStr
)+1;
1716 IMPL_RTL_STRINGNAME( newFromStr_WithLength
)( ppThis
, pCharStrStart
, pCharStr
-pCharStrStart
);
1718 return nIndex
+(pCharStr
-pOrgCharStr
)+1;
1724 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */