blob: a505fabedce1786b5e5931e65bbaf2e7849476e2 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
/* ======================================================================= */
/* Internal C-String help functions which could be used without the */
/* String-Class */
/* ======================================================================= */
/*
inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
const IMPL_RTL_STRCODE* pSrc,
sal_Int32 nCount )
{
while ( nCount > 0 )
{
*pDest = *pSrc;
pDest++;
pSrc++;
nCount--;
}
}
*/
#define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \
{ \
IMPL_RTL_STRCODE* __mm_pDest = _pDest; \
const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \
sal_Int32 __mm_nCount = _nCount; \
while ( __mm_nCount > 0 ) \
{ \
*__mm_pDest = *__mm_pSrc; \
__mm_pDest++; \
__mm_pSrc++; \
__mm_nCount--; \
} \
}
/* ======================================================================= */
/* C-String functions which could be used without the String-Class */
/* ======================================================================= */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( getLength )( const IMPL_RTL_STRCODE* pStr )
{
const IMPL_RTL_STRCODE* pTempStr = pStr;
while( *pTempStr )
pTempStr++;
return pTempStr-pStr;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1,
const IMPL_RTL_STRCODE* pStr2 )
{
sal_Int32 nRet;
while ( ((nRet = ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr1)))-
((sal_Int32)(IMPL_RTL_USTRCODE(*pStr2)))) == 0) &&
*pStr2 )
{
pStr1++;
pStr2++;
}
return nRet;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
sal_Int32 nStr1Len,
const IMPL_RTL_STRCODE* pStr2,
sal_Int32 nStr2Len )
{
sal_Int32 nRet = nStr1Len - nStr2Len;
int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
--pStr1;
--pStr2;
while( (--nCount >= 0) && (*++pStr1 == *++pStr2) );
if( nCount >= 0 )
nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))
- ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
return nRet;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
sal_Int32 nStr1Len,
const IMPL_RTL_STRCODE* pStr2,
sal_Int32 nStr2Len,
sal_Int32 nShortenedLength )
{
const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
sal_Int32 nRet;
while ( (nShortenedLength > 0) &&
(pStr1 < pStr1End) && (pStr2 < pStr2End) )
{
nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))-
((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
if ( nRet )
return nRet;
nShortenedLength--;
pStr1++;
pStr2++;
}
if ( nShortenedLength <= 0 )
return 0;
return nStr1Len - nStr2Len;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
sal_Int32 nStr1Len,
const IMPL_RTL_STRCODE* pStr2,
sal_Int32 nStr2Len )
{
const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
sal_Int32 nRet;
while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
{
pStr1Run--;
pStr2Run--;
nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1Run )))-
((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2Run )));
if ( nRet )
return nRet;
}
return nStr1Len - nStr2Len;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
const IMPL_RTL_STRCODE* pStr2 )
{
sal_Int32 nRet;
sal_Int32 c1;
sal_Int32 c2;
do
{
/* If character between 'A' and 'Z', than convert it to lowercase */
c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
if ( (c1 >= 65) && (c1 <= 90) )
c1 += 32;
if ( (c2 >= 65) && (c2 <= 90) )
c2 += 32;
nRet = c1-c2;
if ( nRet != 0 )
return nRet;
pStr1++;
pStr2++;
}
while ( c2 );
return 0;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
sal_Int32 nStr1Len,
const IMPL_RTL_STRCODE* pStr2,
sal_Int32 nStr2Len )
{
const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
sal_Int32 nRet;
sal_Int32 c1;
sal_Int32 c2;
while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
{
/* If character between 'A' and 'Z', than convert it to lowercase */
c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
if ( (c1 >= 65) && (c1 <= 90) )
c1 += 32;
if ( (c2 >= 65) && (c2 <= 90) )
c2 += 32;
nRet = c1-c2;
if ( nRet != 0 )
return nRet;
pStr1++;
pStr2++;
}
return nStr1Len - nStr2Len;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
sal_Int32 nStr1Len,
const IMPL_RTL_STRCODE* pStr2,
sal_Int32 nStr2Len,
sal_Int32 nShortenedLength )
{
const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
sal_Int32 nRet;
sal_Int32 c1;
sal_Int32 c2;
while ( (nShortenedLength > 0) &&
(pStr1 < pStr1End) && (pStr2 < pStr2End) )
{
/* If character between 'A' and 'Z', than convert it to lowercase */
c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
if ( (c1 >= 65) && (c1 <= 90) )
c1 += 32;
if ( (c2 >= 65) && (c2 <= 90) )
c2 += 32;
nRet = c1-c2;
if ( nRet != 0 )
return nRet;
nShortenedLength--;
pStr1++;
pStr2++;
}
if ( nShortenedLength <= 0 )
return 0;
return nStr1Len - nStr2Len;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
{
return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
sal_Int32 nLen )
{
sal_Int32 h = nLen;
if ( nLen < 256 )
{
while ( nLen > 0 )
{
h = (h*37) + IMPL_RTL_USTRCODE( *pStr );
pStr++;
nLen--;
}
}
else
{
sal_Int32 nSkip;
const IMPL_RTL_STRCODE* pEndStr = pStr+nLen-5;
/* only sample some characters */
/* the first 3, some characters between, and the last 5 */
h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
pStr++;
h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
pStr++;
h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
pStr++;
if ( nLen < 32 )
nSkip = nLen / 4;
else
nSkip = nLen / 8;
nLen -= 8;
while ( nLen > 0 )
{
h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
pStr += nSkip;
nLen -= nSkip;
}
h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
pEndStr++;
h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
pEndStr++;
h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
pEndStr++;
h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
pEndStr++;
h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
}
return h;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
IMPL_RTL_STRCODE c )
{
const IMPL_RTL_STRCODE* pTempStr = pStr;
while ( *pTempStr )
{
if ( *pTempStr == c )
return pTempStr-pStr;
pTempStr++;
}
return -1;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
sal_Int32 nLen,
IMPL_RTL_STRCODE c )
{
const IMPL_RTL_STRCODE* pTempStr = pStr;
while ( nLen > 0 )
{
if ( *pTempStr == c )
return pTempStr-pStr;
pTempStr++;
nLen--;
}
return -1;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
IMPL_RTL_STRCODE c )
{
return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
sal_Int32 nLen,
IMPL_RTL_STRCODE c )
{
pStr += nLen;
while ( nLen > 0 )
{
nLen--;
pStr--;
if ( *pStr == c )
return nLen;
}
return -1;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
const IMPL_RTL_STRCODE* pSubStr )
{
return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
sal_Int32 nStrLen,
const IMPL_RTL_STRCODE* pSubStr,
sal_Int32 nSubLen )
{
/* faster search for a single character */
if ( nSubLen < 2 )
{
/* an empty SubString is always not foundable */
if ( nSubLen == 1 )
{
IMPL_RTL_STRCODE c = *pSubStr;
const IMPL_RTL_STRCODE* pTempStr = pStr;
while ( nStrLen > 0 )
{
if ( *pTempStr == c )
return pTempStr-pStr;
pTempStr++;
nStrLen--;
}
}
}
else
{
const IMPL_RTL_STRCODE* pTempStr = pStr;
while ( nStrLen > 0 )
{
if ( *pTempStr == *pSubStr )
{
/* Compare SubString */
if ( nSubLen <= nStrLen )
{
const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
sal_Int32 nTempLen = nSubLen;
while ( nTempLen )
{
if ( *pTempStr1 != *pTempStr2 )
break;
pTempStr1++;
pTempStr2++;
nTempLen--;
}
if ( !nTempLen )
return pTempStr-pStr;
}
else
break;
}
nStrLen--;
pTempStr++;
}
}
return -1;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
const IMPL_RTL_STRCODE* pSubStr )
{
return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
sal_Int32 nStrLen,
const IMPL_RTL_STRCODE* pSubStr,
sal_Int32 nSubLen )
{
/* faster search for a single character */
if ( nSubLen < 2 )
{
/* an empty SubString is always not foundable */
if ( nSubLen == 1 )
{
IMPL_RTL_STRCODE c = *pSubStr;
pStr += nStrLen;
while ( nStrLen > 0 )
{
nStrLen--;
pStr--;
if ( *pStr == c )
return nStrLen;
}
}
}
else
{
pStr += nStrLen;
nStrLen -= nSubLen;
pStr -= nSubLen;
while ( nStrLen >= 0 )
{
const IMPL_RTL_STRCODE* pTempStr1 = pStr;
const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
sal_Int32 nTempLen = nSubLen;
while ( nTempLen )
{
if ( *pTempStr1 != *pTempStr2 )
break;
pTempStr1++;
pTempStr2++;
nTempLen--;
}
if ( !nTempLen )
return nStrLen;
nStrLen--;
pStr--;
}
}
return -1;
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
IMPL_RTL_STRCODE cOld,
IMPL_RTL_STRCODE cNew )
{
while ( *pStr )
{
if ( *pStr == cOld )
*pStr = cNew;
pStr++;
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
sal_Int32 nLen,
IMPL_RTL_STRCODE cOld,
IMPL_RTL_STRCODE cNew )
{
while ( nLen > 0 )
{
if ( *pStr == cOld )
*pStr = cNew;
pStr++;
nLen--;
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
{
while ( *pStr )
{
/* Between A-Z (65-90), than to lowercase (+32) */
if ( (*pStr >= 65) && (*pStr <= 90) )
*pStr += 32;
pStr++;
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
sal_Int32 nLen )
{
while ( nLen > 0 )
{
/* Between A-Z (65-90), than to lowercase (+32) */
if ( (*pStr >= 65) && (*pStr <= 90) )
*pStr += 32;
pStr++;
nLen--;
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
{
while ( *pStr )
{
/* Between a-z (97-122), than to uppercase (-32) */
if ( (*pStr >= 97) && (*pStr <= 122) )
*pStr -= 32;
pStr++;
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
sal_Int32 nLen )
{
while ( nLen > 0 )
{
/* Between a-z (97-122), than to uppercase (-32) */
if ( (*pStr >= 97) && (*pStr <= 122) )
*pStr -= 32;
pStr++;
nLen--;
}
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
{
return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
{
sal_Int32 nPreSpaces = 0;
sal_Int32 nPostSpaces = 0;
sal_Int32 nIndex = nLen-1;
while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
nPreSpaces++;
while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
{
nPostSpaces++;
nIndex--;
}
if ( nPostSpaces )
{
nLen -= nPostSpaces;
*(pStr+nLen) = 0;
}
if ( nPreSpaces )
{
IMPL_RTL_STRCODE* pNewStr = pStr+nPreSpaces;
nLen -= nPreSpaces;
nIndex = nLen;
while ( nIndex )
{
*pStr = *pNewStr;
pStr++;
pNewStr++;
nIndex--;
}
*pStr = 0;
}
return nLen;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
{
if ( b )
{
*pStr = 't';
pStr++;
*pStr = 'r';
pStr++;
*pStr = 'u';
pStr++;
*pStr = 'e';
pStr++;
*pStr = 0;
return 4;
}
else
{
*pStr = 'f';
pStr++;
*pStr = 'a';
pStr++;
*pStr = 'l';
pStr++;
*pStr = 's';
pStr++;
*pStr = 'e';
pStr++;
*pStr = 0;
return 5;
}
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
IMPL_RTL_STRCODE c )
{
*pStr++ = c;
*pStr = 0;
return 1;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
sal_Int32 n,
sal_Int16 nRadix )
{
sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32];
sal_Char* pBuf = aBuf;
sal_Int32 nLen = 0;
sal_uInt32 nValue;
/* Radix must be valid */
if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
nRadix = 10;
/* is value negativ */
if ( n < 0 )
{
*pStr = '-';
pStr++;
nLen++;
nValue = -n; /* FIXME this code is not portable for n == -2147483648
(smallest negative value for sal_Int32) */
}
else
nValue = n;
/* create a recursive buffer with all values, except the last one */
do
{
sal_Char nDigit = (sal_Char)(nValue % nRadix);
nValue /= nRadix;
if ( nDigit > 9 )
*pBuf = (nDigit-10) + 'a';
else
*pBuf = (nDigit + '0' );
pBuf++;
}
while ( nValue > 0 );
/* copy the values in the right direction into the destination buffer */
do
{
pBuf--;
*pStr = *pBuf;
pStr++;
nLen++;
}
while ( pBuf != aBuf );
*pStr = 0;
return nLen;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
sal_Int64 n,
sal_Int16 nRadix )
{
sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64];
sal_Char* pBuf = aBuf;
sal_Int32 nLen = 0;
sal_uInt64 nValue;
/* Radix must be valid */
if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
nRadix = 10;
/* is value negativ */
if ( n < 0 )
{
*pStr = '-';
pStr++;
nLen++;
nValue = -n; /* FIXME this code is not portable for
n == -9223372036854775808 (smallest negative value for
sal_Int64) */
}
else
nValue = n;
/* create a recursive buffer with all values, except the last one */
do
{
sal_Char nDigit = (sal_Char)(nValue % nRadix);
nValue /= nRadix;
if ( nDigit > 9 )
*pBuf = (nDigit-10) + 'a';
else
*pBuf = (nDigit + '0' );
pBuf++;
}
while ( nValue > 0 );
/* copy the values in the right direction into the destination buffer */
do
{
pBuf--;
*pStr = *pBuf;
pStr++;
nLen++;
}
while ( pBuf != aBuf );
*pStr = 0;
return nLen;
}
/* ----------------------------------------------------------------------- */
sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
{
if ( *pStr == '1' )
return sal_True;
if ( (*pStr == 'T') || (*pStr == 't') )
{
pStr++;
if ( (*pStr == 'R') || (*pStr == 'r') )
{
pStr++;
if ( (*pStr == 'U') || (*pStr == 'u') )
{
pStr++;
if ( (*pStr == 'E') || (*pStr == 'e') )
return sal_True;
}
}
}
return sal_False;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
sal_Int16 nRadix )
{
sal_Bool bNeg;
sal_Int16 nDigit;
sal_Int32 n = 0;
if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
nRadix = 10;
/* Skip whitespaces */
while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
pStr++;
if ( *pStr == '-' )
{
bNeg = sal_True;
pStr++;
}
else
{
if ( *pStr == '+' )
pStr++;
bNeg = sal_False;
}
while ( *pStr )
{
nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
if ( nDigit < 0 )
break;
n *= nRadix;
n += nDigit;
pStr++;
}
if ( bNeg )
return -n;
else
return n;
}
/* ----------------------------------------------------------------------- */
sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
sal_Int16 nRadix )
{
sal_Bool bNeg;
sal_Int16 nDigit;
sal_Int64 n = 0;
if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
nRadix = 10;
/* Skip whitespaces */
while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
pStr++;
if ( *pStr == '-' )
{
bNeg = sal_True;
pStr++;
}
else
{
if ( *pStr == '+' )
pStr++;
bNeg = sal_False;
}
while ( *pStr )
{
nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
if ( nDigit < 0 )
break;
n *= nRadix;
n += nDigit;
pStr++;
}
if ( bNeg )
return -n;
else
return n;
}
/* ======================================================================= */
/* Internal String-Class help functions */
/* ======================================================================= */
static IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
{
IMPL_RTL_STRINGDATA * pData
= (SAL_INT_CAST(sal_uInt32, nLen)
<= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
/ sizeof (IMPL_RTL_STRCODE)))
? (IMPL_RTL_STRINGDATA *) rtl_allocateMemory(
sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE))
: NULL;
if (pData != NULL) {
pData->refCount = 1;
pData->length = nLen;
pData->buffer[nLen] = 0;
}
return pData;
}
/* ----------------------------------------------------------------------- */
static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr,
sal_Int32 nCount )
{
IMPL_RTL_STRCODE* pDest;
const IMPL_RTL_STRCODE* pSrc;
IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
OSL_ASSERT(pData != NULL);
pDest = pData->buffer;
pSrc = pStr->buffer;
while ( nCount > 0 )
{
*pDest = *pSrc;
pDest++;
pSrc++;
nCount--;
}
*ppThis = pData;
return pDest;
}
/* ======================================================================= */
/* String-Class functions */
/* ======================================================================= */
#define IMPL_RTL_AQUIRE( pThis ) \
{ \
if (!SAL_STRING_IS_STATIC (pThis)) \
osl_incrementInterlockedCount( &((pThis)->refCount) ); \
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
{
IMPL_RTL_AQUIRE( pThis );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
{
if (SAL_STRING_IS_STATIC (pThis))
return;
/* OString doesn't have an 'intern' */
#ifdef IMPL_RTL_INTERN
if (SAL_STRING_IS_INTERN (pThis))
{
internRelease (pThis);
return;
}
#endif
if ( pThis->refCount == 1 ||
!osl_decrementInterlockedCount( &(pThis->refCount) ) )
{
rtl_freeMemory( pThis );
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
{
if ( *ppThis)
IMPL_RTL_STRINGNAME( release )( *ppThis );
*ppThis = (IMPL_RTL_STRINGDATA*) (&IMPL_RTL_EMPTYSTRING);
IMPL_RTL_AQUIRE( *ppThis );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
{
if ( nLen <= 0 )
IMPL_RTL_STRINGNAME( new )( ppThis );
else
{
if ( *ppThis)
IMPL_RTL_STRINGNAME( release )( *ppThis );
*ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
OSL_ASSERT(*ppThis != NULL);
(*ppThis)->length = 0;
{
IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
while ( nLen >= 0 )
{
*pTempStr = 0;
pTempStr++;
nLen--;
}
}
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
const IMPL_RTL_STRINGDATA* pStr )
{
IMPL_RTL_STRINGDATA* pOrg;
if ( !pStr->length )
{
IMPL_RTL_STRINGNAME( new )( ppThis );
return;
}
pOrg = *ppThis;
*ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
OSL_ASSERT(*ppThis != NULL);
rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
/* must be done at least, if pStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
const IMPL_RTL_STRCODE* pCharStr )
{
IMPL_RTL_STRCODE* pBuffer;
IMPL_RTL_STRINGDATA* pOrg;
sal_Int32 nLen;
if ( pCharStr )
{
const IMPL_RTL_STRCODE* pTempStr = pCharStr;
while( *pTempStr )
pTempStr++;
nLen = pTempStr-pCharStr;
}
else
nLen = 0;
if ( !nLen )
{
IMPL_RTL_STRINGNAME( new )( ppThis );
return;
}
pOrg = *ppThis;
*ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
OSL_ASSERT(*ppThis != NULL);
pBuffer = (*ppThis)->buffer;
do
{
*pBuffer = *pCharStr;
pBuffer++;
pCharStr++;
}
while ( *pCharStr );
/* must be done at least, if pCharStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
const IMPL_RTL_STRCODE* pCharStr,
sal_Int32 nLen )
{
IMPL_RTL_STRINGDATA* pOrg;
if ( !pCharStr || (nLen <= 0) )
{
IMPL_RTL_STRINGNAME( new )( ppThis );
return;
}
pOrg = *ppThis;
*ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
OSL_ASSERT(*ppThis != NULL);
rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
/* must be done at least, if pCharStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr )
{
/* must be done at first, if pStr == *ppThis */
IMPL_RTL_AQUIRE( pStr );
if ( *ppThis )
IMPL_RTL_STRINGNAME( release )( *ppThis );
*ppThis = pStr;
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
{
return pThis->length;
}
/* ----------------------------------------------------------------------- */
IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
{
return pThis->buffer;
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pLeft,
IMPL_RTL_STRINGDATA* pRight )
{
IMPL_RTL_STRINGDATA* pOrg = *ppThis;
/* Test for 0-Pointer - if not, change newReplaceStrAt! */
if ( !pRight || !pRight->length )
{
*ppThis = pLeft;
IMPL_RTL_AQUIRE( pLeft );
}
else if ( !pLeft || !pLeft->length )
{
*ppThis = pRight;
IMPL_RTL_AQUIRE( pRight );
}
else
{
IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
OSL_ASSERT(pTempStr != NULL);
rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
*ppThis = pTempStr;
}
/* must be done at least, if left or right == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr,
sal_Int32 nIndex,
sal_Int32 nCount,
IMPL_RTL_STRINGDATA* pNewSubStr )
{
/* Append? */
if ( nIndex >= pStr->length )
{
/* newConcat test, if pNewSubStr is 0 */
IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
return;
}
/* negativ index? */
if ( nIndex < 0 )
{
nCount -= nIndex;
nIndex = 0;
}
/* not more than the String length could be deleted */
if ( nCount >= pStr->length-nIndex )
{
nCount = pStr->length-nIndex;
/* Assign of NewSubStr? */
if ( !nIndex && (nCount >= pStr->length) )
{
if ( !pNewSubStr )
IMPL_RTL_STRINGNAME( new )( ppThis );
else
IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
return;
}
}
/* Assign of Str? */
if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
{
IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
return;
}
{
IMPL_RTL_STRINGDATA* pOrg = *ppThis;
IMPL_RTL_STRCODE* pBuffer;
sal_Int32 nNewLen;
/* Calculate length of the new string */
nNewLen = pStr->length-nCount;
if ( pNewSubStr )
nNewLen += pNewSubStr->length;
/* Alloc New Buffer */
*ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
OSL_ASSERT(*ppThis != NULL);
pBuffer = (*ppThis)->buffer;
if ( nIndex )
{
rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
pBuffer += nIndex;
}
if ( pNewSubStr && pNewSubStr->length )
{
rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
pBuffer += pNewSubStr->length;
}
rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
/* must be done at least, if pStr or pNewSubStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr,
IMPL_RTL_STRCODE cOld,
IMPL_RTL_STRCODE cNew )
{
IMPL_RTL_STRINGDATA* pOrg = *ppThis;
int bChanged = 0;
sal_Int32 nLen = pStr->length;
const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
while ( nLen > 0 )
{
if ( *pCharStr == cOld )
{
/* Copy String */
IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
/* replace/copy rest of the string */
if ( pNewCharStr )
{
*pNewCharStr = cNew;
pNewCharStr++;
pCharStr++;
nLen--;
while ( nLen > 0 )
{
if ( *pCharStr == cOld )
*pNewCharStr = cNew;
else
*pNewCharStr = *pCharStr;
pNewCharStr++;
pCharStr++;
nLen--;
}
}
bChanged = 1;
break;
}
pCharStr++;
nLen--;
}
if ( !bChanged )
{
*ppThis = pStr;
IMPL_RTL_AQUIRE( pStr );
}
/* must be done at least, if pStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr )
{
IMPL_RTL_STRINGDATA* pOrg = *ppThis;
int bChanged = 0;
sal_Int32 nLen = pStr->length;
const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
while ( nLen > 0 )
{
/* Between A-Z (65-90), than to lowercase (+32) */
if ( (*pCharStr >= 65) && (*pCharStr <= 90) )
{
/* Copy String */
IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
/* replace/copy rest of the string */
if ( pNewCharStr )
{
/* to lowercase (+32) */
*pNewCharStr = *pCharStr+32;
pNewCharStr++;
pCharStr++;
nLen--;
while ( nLen > 0 )
{
/* Between A-Z (65-90), than to lowercase (+32) */
if ( (*pCharStr >= 65) && (*pCharStr <= 90) )
*pNewCharStr = *pCharStr+32;
else
*pNewCharStr = *pCharStr;
pNewCharStr++;
pCharStr++;
nLen--;
}
}
bChanged = 1;
break;
}
pCharStr++;
nLen--;
}
if ( !bChanged )
{
*ppThis = pStr;
IMPL_RTL_AQUIRE( pStr );
}
/* must be done at least, if pStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr )
{
IMPL_RTL_STRINGDATA* pOrg = *ppThis;
int bChanged = 0;
sal_Int32 nLen = pStr->length;
const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
while ( nLen > 0 )
{
/* Between a-z (97-122), than to uppercase (-32) */
if ( (*pCharStr >= 97) && (*pCharStr <= 122) )
{
/* Copy String */
IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
/* replace/copy rest of the string */
if ( pNewCharStr )
{
/* to uppercase (-32) */
*pNewCharStr = *pCharStr-32;
pNewCharStr++;
pCharStr++;
nLen--;
while ( nLen > 0 )
{
/* Between a-z (97-122), than to uppercase (-32) */
if ( (*pCharStr >= 97) && (*pCharStr <= 122) )
*pNewCharStr = *pCharStr-32;
else
*pNewCharStr = *pCharStr;
pNewCharStr++;
pCharStr++;
nLen--;
}
}
bChanged = 1;
break;
}
pCharStr++;
nLen--;
}
if ( !bChanged )
{
*ppThis = pStr;
IMPL_RTL_AQUIRE( pStr );
}
/* must be done at least, if pStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr )
{
IMPL_RTL_STRINGDATA* pOrg = *ppThis;
const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
sal_Int32 nPreSpaces = 0;
sal_Int32 nPostSpaces = 0;
sal_Int32 nLen = pStr->length;
sal_Int32 nIndex = nLen-1;
while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
nPreSpaces++;
while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
{
nPostSpaces++;
nIndex--;
}
if ( !nPreSpaces && !nPostSpaces )
{
*ppThis = pStr;
IMPL_RTL_AQUIRE( pStr );
}
else
{
nLen -= nPostSpaces+nPreSpaces;
*ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
OSL_ASSERT(*ppThis != NULL);
if ( *ppThis )
rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
}
/* must be done at least, if pStr == *ppThis */
if ( pOrg )
IMPL_RTL_STRINGNAME( release )( pOrg );
}
/* ----------------------------------------------------------------------- */
sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
IMPL_RTL_STRINGDATA* pStr,
sal_Int32 nToken,
IMPL_RTL_STRCODE cTok,
sal_Int32 nIndex )
{
const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
const IMPL_RTL_STRCODE* pCharStrStart;
const IMPL_RTL_STRCODE* pOrgCharStr;
sal_Int32 nLen = pStr->length-nIndex;
sal_Int32 nTokCount = 0;
// Set ppThis to an empty string and return -1 if either nToken or nIndex is
// negative:
if (nIndex < 0) {
nToken = -1;
}
pCharStr += nIndex;
pOrgCharStr = pCharStr;
pCharStrStart = pCharStr;
while ( nLen > 0 )
{
if ( *pCharStr == cTok )
{
nTokCount++;
if ( nTokCount == nToken )
pCharStrStart = pCharStr+1;
else
{
if ( nTokCount > nToken )
break;
}
}
pCharStr++;
nLen--;
}
if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
{
IMPL_RTL_STRINGNAME( new )( ppThis );
if( (nToken < 0) || (nTokCount < nToken ) )
return -1;
else if( nLen > 0 )
return nIndex+(pCharStr-pOrgCharStr)+1;
else return -1;
}
else
{
IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
if ( nLen )
return nIndex+(pCharStr-pOrgCharStr)+1;
else
return -1;
}
}