LCOV - code coverage report
Current view: top level - tools/source/string - tustring.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 299 348 85.9 %
Date: 2012-08-25 Functions: 33 39 84.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 142 182 78.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       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/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      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 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <string.h>
      21                 :            : 
      22                 :            : #include "boost/static_assert.hpp"
      23                 :            : 
      24                 :            : #include <osl/interlck.h>
      25                 :            : #include <rtl/alloc.h>
      26                 :            : #include <rtl/memory.h>
      27                 :            : #include <rtl/tencinfo.h>
      28                 :            : #include <rtl/instance.hxx>
      29                 :            : #include <tools/string.hxx>
      30                 :            : 
      31                 :            : #include <impstrg.hxx>
      32                 :            : 
      33                 :            : #include <tools/debug.hxx>
      34                 :            : 
      35                 :            : DBG_NAME( UniString )
      36                 :            : 
      37                 :            : #define STRCODE         sal_Unicode
      38                 :            : #define STRCODEU        sal_Unicode
      39                 :            : #define STRING          UniString
      40                 :            : #define STRINGDATA      UniStringData
      41                 :            : #define DBGCHECKSTRING  DbgCheckUniString
      42                 :            : #define STRING_TYPE     rtl_uString
      43                 :            : #define STRING_ACQUIRE  rtl_uString_acquire
      44                 :            : #define STRING_RELEASE  rtl_uString_release
      45                 :            : #define STRING_NEW      rtl_uString_new
      46                 :            : 
      47                 :            : #include <strimp.cxx>
      48                 :            : #include <strucvt.cxx>
      49                 :            : #include <strascii.cxx>
      50                 :            : 
      51                 :          0 : UniString::UniString(char c): mpData(ImplAllocData(1)) { mpData->maStr[0] = c; }
      52                 :            : 
      53                 :     192001 : UniString UniString::CreateFromInt32( sal_Int32 n, sal_Int16 nRadix )
      54                 :            : {
      55         [ +  - ]:     192001 :     return rtl::OUString::valueOf(n, nRadix);
      56                 :            : }
      57                 :            : 
      58                 :            : namespace { struct Empty : public rtl::Static< const UniString, Empty> {}; }
      59                 :            : 
      60                 :      44313 : const UniString& UniString::EmptyString()
      61                 :            : {
      62                 :      44313 :     return Empty::get();
      63                 :            : }
      64                 :            : 
      65                 :      70665 : sal_Int32 UniString::ToInt32() const
      66                 :            : {
      67                 :            :     DBG_CHKTHIS( UniString, DbgCheckUniString );
      68                 :            : 
      69                 :      70665 :     return rtl_ustr_toInt32( mpData->maStr, 10 );
      70                 :            : }
      71                 :            : 
      72                 :          0 : sal_Int64 UniString::ToInt64() const
      73                 :            : {
      74                 :            :     DBG_CHKTHIS( UniString, DbgCheckUniString );
      75                 :            : 
      76                 :          0 :     return rtl_ustr_toInt64( mpData->maStr, 10 );
      77                 :            : }
      78                 :            : 
      79                 :      11892 : xub_StrLen STRING::SearchChar( const STRCODE* pChars, xub_StrLen nIndex ) const
      80                 :            : {
      81                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
      82                 :            : 
      83                 :      11892 :     sal_Int32       nLen = mpData->mnLen;
      84                 :      11892 :     const STRCODE*  pStr = mpData->maStr;
      85                 :      11892 :     pStr += nIndex;
      86         [ +  + ]:      83944 :     while ( nIndex < nLen )
      87                 :            :     {
      88                 :      72102 :         STRCODE         c = *pStr;
      89                 :      72102 :         const STRCODE*  pCompStr = pChars;
      90         [ +  + ]:     413440 :         while ( *pCompStr )
      91                 :            :         {
      92         [ +  + ]:     341388 :             if ( *pCompStr == c )
      93                 :         50 :                 return nIndex;
      94                 :     341338 :             ++pCompStr;
      95                 :            :         }
      96                 :            :         ++pStr,
      97                 :      72052 :         ++nIndex;
      98                 :            :     }
      99                 :            : 
     100                 :      11892 :     return STRING_NOTFOUND;
     101                 :            : }
     102                 :            : 
     103                 :        405 : xub_StrLen STRING::SearchAndReplace( STRCODE c, STRCODE cRep, xub_StrLen nIndex )
     104                 :            : {
     105                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     106                 :            : 
     107                 :        405 :     sal_Int32       nLen = mpData->mnLen;
     108                 :        405 :     const STRCODE*  pStr = mpData->maStr;
     109                 :        405 :     pStr += nIndex;
     110         [ +  + ]:       3870 :     while ( nIndex < nLen )
     111                 :            :     {
     112         [ +  + ]:       3585 :         if ( *pStr == c )
     113                 :            :         {
     114                 :        120 :             ImplCopyData();
     115                 :        120 :             mpData->maStr[nIndex] = cRep;
     116                 :        120 :             return nIndex;
     117                 :            :         }
     118                 :            :         ++pStr,
     119                 :       3465 :         ++nIndex;
     120                 :            :     }
     121                 :            : 
     122                 :        405 :     return STRING_NOTFOUND;
     123                 :            : }
     124                 :            : 
     125                 :       1587 : STRING& STRING::Insert( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen,
     126                 :            :                         xub_StrLen nIndex )
     127                 :            : {
     128                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     129                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     130                 :            : 
     131                 :            :     // Determine string length
     132         [ -  + ]:       1587 :     if ( nPos > rStr.mpData->mnLen )
     133                 :          0 :         nLen = 0;
     134                 :            :     else
     135                 :            :     {
     136                 :            :         // Correct length if necessary
     137                 :       1587 :         sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos;
     138         [ -  + ]:       1587 :         if ( nLen > nMaxLen )
     139                 :          0 :             nLen = static_cast< xub_StrLen >(nMaxLen);
     140                 :            :     }
     141                 :            : 
     142                 :            :     // Detect overflow
     143                 :       1587 :     sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, nLen );
     144                 :            : 
     145         [ -  + ]:       1587 :     if ( !nCopyLen )
     146                 :          0 :         return *this;
     147                 :            : 
     148                 :            :     // Correct index if necessary
     149         [ -  + ]:       1587 :     if ( nIndex > mpData->mnLen )
     150                 :          0 :         nIndex = static_cast< xub_StrLen >(mpData->mnLen);
     151                 :            : 
     152                 :            :     // Determine new length and allocate string
     153                 :       1587 :     STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
     154                 :            : 
     155                 :            :     // copy string to newdata
     156                 :       1587 :     memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
     157                 :       1587 :     memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr+nPos, nCopyLen*sizeof( STRCODE ) );
     158                 :       1587 :     memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
     159                 :       3174 :             (mpData->mnLen-nIndex)*sizeof( STRCODE ) );
     160                 :            : 
     161                 :            :     // release old data
     162                 :       1587 :     STRING_RELEASE((STRING_TYPE *)mpData);
     163                 :       1587 :     mpData = pNewData;
     164                 :            : 
     165                 :       1587 :     return *this;
     166                 :            : }
     167                 :            : 
     168                 :     998876 : static sal_Int32 ImplStringICompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2,
     169                 :            :                                                 sal_Int32 nCount )
     170                 :            : {
     171                 :     998876 :     sal_Int32   nRet = 0;
     172                 :            :     STRCODE     c1;
     173                 :            :     STRCODE     c2;
     174         [ +  + ]:    2108897 :     do
     175                 :            :     {
     176         [ +  + ]:    2171161 :         if ( !nCount )
     177                 :      62264 :             break;
     178                 :            : 
     179                 :            :         // convert if char is between 'A' and 'Z'
     180                 :    2108897 :         c1 = *pStr1;
     181                 :    2108897 :         c2 = *pStr2;
     182 [ +  + ][ +  + ]:    2108897 :         if ( (c1 >= 65) && (c1 <= 90) )
     183                 :     465837 :             c1 += 32;
     184 [ +  + ][ +  + ]:    2108897 :         if ( (c2 >= 65) && (c2 <= 90) )
     185                 :     905668 :             c2 += 32;
     186                 :    2108897 :         nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
     187                 :            : 
     188                 :            :         ++pStr1,
     189                 :            :         ++pStr2,
     190                 :    2108897 :         --nCount;
     191                 :            :     }
     192                 :            :     while ( nRet == 0 );
     193                 :            : 
     194                 :     998876 :     return nRet;
     195                 :            : }
     196                 :            : 
     197                 :          0 : sal_Bool STRING::EqualsIgnoreCaseAscii( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
     198                 :            : {
     199                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     200                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     201                 :            : 
     202                 :            :     // Are there enough codes for comparing?
     203         [ #  # ]:          0 :     if ( nIndex > mpData->mnLen )
     204                 :          0 :         return (rStr.mpData->mnLen == 0);
     205                 :          0 :     sal_Int32 nMaxLen = mpData->mnLen-nIndex;
     206         [ #  # ]:          0 :     if ( nMaxLen < nLen )
     207                 :            :     {
     208         [ #  # ]:          0 :         if ( rStr.mpData->mnLen != nMaxLen )
     209                 :          0 :             return sal_False;
     210                 :          0 :         nLen = static_cast< xub_StrLen >(nMaxLen);
     211                 :            :     }
     212                 :            : 
     213                 :          0 :     return (ImplStringICompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
     214                 :            : }
     215                 :            : 
     216                 :     715365 : StringCompare STRING::CompareIgnoreCaseToAscii( const STRING& rStr,
     217                 :            :                                                 xub_StrLen nLen ) const
     218                 :            : {
     219                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     220                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     221                 :            : 
     222         [ +  + ]:     715365 :     if ( mpData == rStr.mpData )
     223                 :       6969 :         return COMPARE_EQUAL;
     224                 :            : 
     225                 :            :     // determine maximal length
     226         [ +  - ]:     708396 :     if ( mpData->mnLen < nLen )
     227                 :     708396 :         nLen = static_cast< xub_StrLen >(mpData->mnLen+1);
     228         [ +  + ]:     708396 :     if ( rStr.mpData->mnLen < nLen )
     229                 :     400664 :         nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1);
     230                 :            : 
     231                 :     708396 :     sal_Int32 nCompare = ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen );
     232                 :            : 
     233         [ +  + ]:     708396 :     if ( nCompare == 0 )
     234                 :       9502 :         return COMPARE_EQUAL;
     235         [ +  + ]:     698894 :     else if ( nCompare < 0 )
     236                 :     311933 :         return COMPARE_LESS;
     237                 :            :     else
     238                 :     715365 :         return COMPARE_GREATER;
     239                 :            : }
     240                 :            : 
     241                 :        194 : STRING& STRING::Fill( xub_StrLen nCount, STRCODE cFillChar )
     242                 :            : {
     243                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     244                 :            : 
     245         [ +  + ]:        194 :     if ( !nCount )
     246                 :         26 :         return *this;
     247                 :            : 
     248                 :            :     // extend string if fill length is larger
     249         [ +  - ]:        168 :     if ( nCount > mpData->mnLen )
     250                 :            :     {
     251                 :            :         // allocate string of new length
     252                 :        168 :         STRINGDATA* pNewData = ImplAllocData( nCount );
     253                 :        168 :         STRING_RELEASE((STRING_TYPE *)mpData);
     254                 :        168 :         mpData = pNewData;
     255                 :            :     }
     256                 :            :     else
     257                 :          0 :         ImplCopyData();
     258                 :            : 
     259                 :        168 :     STRCODE* pStr = mpData->maStr;
     260         [ +  + ]:       1228 :     do
     261                 :            :     {
     262                 :       1228 :         *pStr = cFillChar;
     263                 :            :         ++pStr,
     264                 :       1228 :         --nCount;
     265                 :            :     }
     266                 :            :     while ( nCount );
     267                 :            : 
     268                 :        194 :     return *this;
     269                 :            : }
     270                 :            : 
     271                 :      16620 : STRING& STRING::Expand( xub_StrLen nCount, STRCODE cExpandChar )
     272                 :            : {
     273                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     274                 :            : 
     275                 :            :     // return if string doesn't need expanding
     276                 :      16620 :     sal_Int32 nLen = mpData->mnLen;
     277         [ -  + ]:      16620 :     if ( nCount <= nLen )
     278                 :          0 :         return *this;
     279                 :            : 
     280                 :            :     // allocate string of new size
     281                 :      16620 :     STRINGDATA* pNewData = ImplAllocData( nCount );
     282                 :            : 
     283                 :            :     // copy from old string
     284                 :      16620 :     memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
     285                 :            : 
     286                 :            :     // and expand using the given character
     287                 :      16620 :     STRCODE* pStr = pNewData->maStr;
     288                 :      16620 :     pStr += nLen;
     289         [ +  + ]:      65857 :     for (sal_Int32 i = nCount - nLen; i > 0; --i) {
     290                 :      49237 :         *pStr++ = cExpandChar;
     291                 :            :     }
     292                 :            : 
     293                 :            :     // free old string
     294                 :      16620 :     STRING_RELEASE((STRING_TYPE *)mpData);
     295                 :      16620 :     mpData = pNewData;
     296                 :            : 
     297                 :      16620 :     return *this;
     298                 :            : }
     299                 :            : 
     300                 :       3208 : STRCODE* STRING::GetBufferAccess()
     301                 :            : {
     302                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     303                 :            : 
     304                 :            :     // Copy data if necessary
     305         [ +  + ]:       3208 :     if ( mpData->mnLen )
     306                 :       3188 :         ImplCopyData();
     307                 :            : 
     308                 :            :     // return pointer to string data
     309                 :       3208 :     return mpData->maStr;
     310                 :            : }
     311                 :            : 
     312                 :        935 : void STRING::ReleaseBufferAccess( xub_StrLen nLen )
     313                 :            : {
     314                 :            :     // String not consinstent, thus no functionality test
     315                 :            :     DBG_CHKTHIS( STRING, NULL );
     316                 :            :     DBG_ASSERT( mpData->mnRefCount == 1, "String::ReleaseCharStr() called for String with RefCount" );
     317                 :            : 
     318         [ +  - ]:        935 :     if ( nLen > mpData->mnLen )
     319                 :        935 :         nLen = ImplStringLen( mpData->maStr );
     320                 :            :     OSL_ASSERT(nLen <= mpData->mnLen);
     321         [ -  + ]:        935 :     if ( !nLen )
     322                 :            :     {
     323                 :          0 :         STRING_NEW((STRING_TYPE **)&mpData);
     324                 :            :     }
     325                 :            :     // shorten buffer is difference > 8 chars
     326         [ -  + ]:        935 :     else if ( mpData->mnLen - nLen > 8 )
     327                 :            :     {
     328                 :          0 :         STRINGDATA* pNewData = ImplAllocData( nLen );
     329                 :          0 :         memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
     330                 :          0 :         STRING_RELEASE((STRING_TYPE *)mpData);
     331                 :          0 :         mpData = pNewData;
     332                 :            :     }
     333                 :            :     else
     334                 :        935 :         mpData->mnLen = nLen;
     335                 :        935 : }
     336                 :            : 
     337                 :          0 : STRCODE* STRING::AllocBuffer( xub_StrLen nLen )
     338                 :            : {
     339                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     340                 :            : 
     341                 :          0 :     STRING_RELEASE((STRING_TYPE *)mpData);
     342         [ #  # ]:          0 :     if ( nLen )
     343                 :          0 :         mpData = ImplAllocData( nLen );
     344                 :            :     else
     345                 :            :     {
     346                 :          0 :         mpData = NULL;
     347                 :          0 :         STRING_NEW((STRING_TYPE **)&mpData);
     348                 :            :     }
     349                 :            : 
     350                 :          0 :     return mpData->maStr;
     351                 :            : }
     352                 :            : 
     353                 :          0 : STRING::STRING( STRCODE c )
     354                 :            : {
     355                 :            :     DBG_CTOR( STRING, DBGCHECKSTRING );
     356                 :            :     DBG_ASSERT( c, "String::String() - c is 0" );
     357                 :            : 
     358                 :            :     // Initalize maintenance data
     359                 :          0 :     mpData = ImplAllocData( 1 );
     360                 :          0 :     mpData->maStr[0] = c;
     361                 :          0 : }
     362                 :            : 
     363                 :      53638 : STRING& STRING::Insert( STRCODE c, xub_StrLen nIndex )
     364                 :            : {
     365                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     366                 :            : 
     367                 :            :     // Don't insert 0 char or string size is maximum
     368 [ +  - ][ -  + ]:      53638 :     if ( !c || (mpData->mnLen == STRING_MAXLEN) )
     369                 :          0 :         return *this;
     370                 :            : 
     371                 :            :     // Adjust string index
     372         [ +  + ]:      53638 :     if ( nIndex > mpData->mnLen )
     373                 :       3802 :         nIndex = static_cast< xub_StrLen >(mpData->mnLen);
     374                 :            : 
     375                 :            :     // allocate string of new size
     376                 :      53638 :     STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+1 );
     377                 :            : 
     378                 :            :     // copy string
     379                 :      53638 :     memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
     380                 :      53638 :     pNewData->maStr[nIndex] = c;
     381                 :      53638 :     memcpy( pNewData->maStr+nIndex+1, mpData->maStr+nIndex,
     382                 :     107276 :             (mpData->mnLen-nIndex)*sizeof( STRCODE ) );
     383                 :            : 
     384                 :            :     // free old data
     385                 :      53638 :     STRING_RELEASE((STRING_TYPE *)mpData);
     386                 :      53638 :     mpData = pNewData;
     387                 :            : 
     388                 :      53638 :     return *this;
     389                 :            : }
     390                 :            : 
     391                 :      14616 : STRING& STRING::ToUpperAscii()
     392                 :            : {
     393                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     394                 :            : 
     395                 :      14616 :     sal_Int32 nIndex = 0;
     396                 :      14616 :     sal_Int32 nLen = mpData->mnLen;
     397                 :      14616 :     STRCODE*    pStr = mpData->maStr;
     398         [ +  + ]:      37625 :     while ( nIndex < nLen )
     399                 :            :     {
     400                 :            :         // convert char if between 'a' and 'z'
     401 [ +  + ][ +  - ]:      23009 :         if ( (*pStr >= 97) && (*pStr <= 122) )
     402                 :            :         {
     403                 :            :             // allocate string of new size
     404                 :       1967 :             pStr = ImplCopyStringData( pStr );
     405                 :       1967 :             *pStr -= 32;
     406                 :            :         }
     407                 :            : 
     408                 :            :         ++pStr,
     409                 :      23009 :         ++nIndex;
     410                 :            :     }
     411                 :            : 
     412                 :      14616 :     return *this;
     413                 :            : }
     414                 :            : 
     415                 :    4460447 : StringCompare STRING::CompareTo( const STRING& rStr, xub_StrLen nLen ) const
     416                 :            : {
     417                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     418                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     419                 :            : 
     420         [ +  + ]:    4460447 :     if ( mpData == rStr.mpData )
     421                 :      22297 :         return COMPARE_EQUAL;
     422                 :            : 
     423                 :            :     // determine maximal length
     424         [ +  + ]:    4438150 :     if ( mpData->mnLen < nLen )
     425                 :    4385047 :         nLen = static_cast< xub_StrLen >(mpData->mnLen+1);
     426         [ +  + ]:    4438150 :     if ( rStr.mpData->mnLen < nLen )
     427                 :    2408123 :         nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1);
     428                 :            : 
     429                 :    4438150 :     sal_Int32 nCompare = ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen );
     430                 :            : 
     431         [ +  + ]:    4438150 :     if ( nCompare == 0 )
     432                 :     744451 :         return COMPARE_EQUAL;
     433         [ +  + ]:    3693699 :     else if ( nCompare < 0 )
     434                 :    2210206 :         return COMPARE_LESS;
     435                 :            :     else
     436                 :    4460447 :         return COMPARE_GREATER;
     437                 :            : }
     438                 :            : 
     439                 :   26215418 : sal_Bool STRING::Equals( const STRING& rStr ) const
     440                 :            : {
     441                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     442                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     443                 :            : 
     444         [ +  + ]:   26215418 :     if ( mpData == rStr.mpData )
     445                 :    6915214 :         return sal_True;
     446                 :            : 
     447         [ +  + ]:   19300204 :     if ( mpData->mnLen != rStr.mpData->mnLen )
     448                 :   16121410 :         return sal_False;
     449                 :            : 
     450                 :   26215418 :     return (ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
     451                 :            : }
     452                 :            : 
     453                 :     563044 : sal_Bool STRING::EqualsIgnoreCaseAscii( const STRING& rStr ) const
     454                 :            : {
     455                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     456                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     457                 :            : 
     458         [ +  + ]:     563044 :     if ( mpData == rStr.mpData )
     459                 :      12732 :         return sal_True;
     460                 :            : 
     461         [ +  + ]:     550312 :     if ( mpData->mnLen != rStr.mpData->mnLen )
     462                 :     259832 :         return sal_False;
     463                 :            : 
     464                 :            :     // compare string while ignoring case
     465                 :     563044 :     return (ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
     466                 :            : }
     467                 :            : 
     468                 :      23663 : sal_Bool STRING::Equals( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
     469                 :            : {
     470                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     471                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     472                 :            : 
     473                 :            :     // Are there enough codes for comparing?
     474         [ -  + ]:      23663 :     if ( nIndex > mpData->mnLen )
     475                 :          0 :         return (rStr.mpData->mnLen == 0);
     476                 :      23663 :     sal_Int32 nMaxLen = mpData->mnLen-nIndex;
     477         [ -  + ]:      23663 :     if ( nMaxLen < nLen )
     478                 :            :     {
     479         [ #  # ]:          0 :         if ( rStr.mpData->mnLen != nMaxLen )
     480                 :          0 :             return sal_False;
     481                 :          0 :         nLen = static_cast< xub_StrLen >(nMaxLen);
     482                 :            :     }
     483                 :            : 
     484                 :      23663 :     return (ImplStringCompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
     485                 :            : }
     486                 :            : 
     487                 :          0 : sal_Bool STRING::Equals( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const
     488                 :            : {
     489                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     490                 :            : 
     491                 :            :     // Are there enough codes for comparing?
     492         [ #  # ]:          0 :     if ( nIndex > mpData->mnLen )
     493                 :          0 :         return (*pCharStr == 0);
     494                 :            : 
     495                 :          0 :     return (ImplStringCompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0);
     496                 :            : }
     497                 :            : 
     498                 :      72204 : xub_StrLen STRING::Match( const STRING& rStr ) const
     499                 :            : {
     500                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     501                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     502                 :            : 
     503                 :            :     // return if string is empty
     504         [ +  + ]:      72204 :     if ( !mpData->mnLen )
     505                 :       1662 :         return STRING_MATCH;
     506                 :            : 
     507                 :            :     // Search the string for unmatching chars
     508                 :      70542 :     const STRCODE*  pStr1 = mpData->maStr;
     509                 :      70542 :     const STRCODE*  pStr2 = rStr.mpData->maStr;
     510                 :      70542 :     xub_StrLen      i = 0;
     511         [ +  - ]:      97278 :     while ( i < mpData->mnLen )
     512                 :            :     {
     513                 :            :         // Abort on the first unmatching char
     514         [ +  + ]:      97278 :         if ( *pStr1 != *pStr2 )
     515                 :      70542 :             return i;
     516                 :            :         ++pStr1,
     517                 :            :         ++pStr2,
     518                 :      26736 :         ++i;
     519                 :            :     }
     520                 :            : 
     521                 :      72204 :     return STRING_MATCH;
     522                 :            : }
     523                 :            : 
     524                 :        811 : xub_StrLen STRING::SearchBackward( STRCODE c, xub_StrLen nIndex ) const
     525                 :            : {
     526                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     527                 :            : 
     528         [ +  - ]:        811 :     if ( nIndex > mpData->mnLen )
     529                 :        811 :         nIndex = (xub_StrLen)mpData->mnLen;
     530                 :            : 
     531                 :        811 :     const STRCODE* pStr = mpData->maStr;
     532                 :        811 :     pStr += nIndex;
     533                 :            : 
     534         [ +  + ]:      26923 :     while ( nIndex )
     535                 :            :     {
     536                 :      26631 :         nIndex--;
     537                 :      26631 :         pStr--;
     538         [ +  + ]:      26631 :         if ( *pStr == c )
     539                 :        519 :             return nIndex;
     540                 :            :     }
     541                 :            : 
     542                 :        811 :     return STRING_NOTFOUND;
     543                 :            : }
     544                 :            : 
     545                 :       9410 : void STRING::SearchAndReplaceAll( const STRING& rStr, const STRING& rRepStr )
     546                 :            : {
     547                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     548                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     549                 :            :     DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );
     550                 :            : 
     551                 :       9410 :     xub_StrLen nSPos = Search( rStr, 0 );
     552         [ -  + ]:       9410 :     while ( nSPos != STRING_NOTFOUND )
     553                 :            :     {
     554                 :          0 :         Replace( nSPos, rStr.Len(), rRepStr );
     555                 :          0 :         nSPos = nSPos + rRepStr.Len();
     556                 :          0 :         nSPos = Search( rStr, nSPos );
     557                 :            :     }
     558                 :       9410 : }
     559                 :            : 
     560                 :         16 : void STRING::SetToken( xub_StrLen nToken, STRCODE cTok, const STRING& rStr,
     561                 :            :                        xub_StrLen nIndex )
     562                 :            : {
     563                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     564                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     565                 :            : 
     566                 :         16 :     const STRCODE*  pStr            = mpData->maStr;
     567                 :         16 :     xub_StrLen      nLen            = (xub_StrLen)mpData->mnLen;
     568                 :         16 :     xub_StrLen      nTok            = 0;
     569                 :         16 :     xub_StrLen      nFirstChar      = nIndex;
     570                 :         16 :     xub_StrLen      i               = nFirstChar;
     571                 :            : 
     572                 :            :     // Determine token position and length
     573                 :         16 :     pStr += i;
     574         [ +  + ]:         60 :     while ( i < nLen )
     575                 :            :     {
     576                 :            :         // Increase token count if match
     577         [ +  + ]:         52 :         if ( *pStr == cTok )
     578                 :            :         {
     579                 :         28 :             ++nTok;
     580                 :            : 
     581         [ +  + ]:         28 :             if ( nTok == nToken )
     582                 :         12 :                 nFirstChar = i+1;
     583                 :            :             else
     584                 :            :             {
     585         [ +  + ]:         16 :                 if ( nTok > nToken )
     586                 :          8 :                     break;
     587                 :            :             }
     588                 :            :         }
     589                 :            : 
     590                 :            :         ++pStr,
     591                 :         44 :         ++i;
     592                 :            :     }
     593                 :            : 
     594         [ +  - ]:         16 :     if ( nTok >= nToken )
     595                 :         16 :         Replace( nFirstChar, i-nFirstChar, rStr );
     596                 :         16 : }
     597                 :            : 
     598                 :      67725 : STRING STRING::GetToken( xub_StrLen nToken, STRCODE cTok, xub_StrLen& rIndex ) const
     599                 :            : {
     600                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     601                 :            : 
     602                 :      67725 :     const STRCODE*  pStr            = mpData->maStr;
     603                 :      67725 :     xub_StrLen      nLen            = (xub_StrLen)mpData->mnLen;
     604                 :      67725 :     xub_StrLen      nTok            = 0;
     605                 :      67725 :     xub_StrLen      nFirstChar      = rIndex;
     606                 :      67725 :     xub_StrLen      i               = nFirstChar;
     607                 :            : 
     608                 :            :     // Determine token position and length
     609                 :      67725 :     pStr += i;
     610         [ +  + ]:    1070912 :     while ( i < nLen )
     611                 :            :     {
     612                 :            :         // Increase token count if match
     613         [ +  + ]:    1037830 :         if ( *pStr == cTok )
     614                 :            :         {
     615                 :      80782 :             ++nTok;
     616                 :            : 
     617         [ +  + ]:      80782 :             if ( nTok == nToken )
     618                 :      29416 :                 nFirstChar = i+1;
     619                 :            :             else
     620                 :            :             {
     621         [ +  + ]:      51366 :                 if ( nTok > nToken )
     622                 :      34643 :                     break;
     623                 :            :             }
     624                 :            :         }
     625                 :            : 
     626                 :            :         ++pStr,
     627                 :    1003187 :         ++i;
     628                 :            :     }
     629                 :            : 
     630         [ +  + ]:      67725 :     if ( nTok >= nToken )
     631                 :            :     {
     632         [ +  + ]:      61365 :         if ( i < nLen )
     633                 :      34643 :             rIndex = i+1;
     634                 :            :         else
     635                 :      26722 :             rIndex = STRING_NOTFOUND;
     636                 :      61365 :         return Copy( nFirstChar, i-nFirstChar );
     637                 :            :     }
     638                 :            :     else
     639                 :            :     {
     640                 :       6360 :         rIndex = STRING_NOTFOUND;
     641                 :      67725 :         return STRING();
     642                 :            :     }
     643                 :            : }
     644                 :            : 
     645                 :      11798 : STRING& STRING::Append( const STRCODE* pCharStr, xub_StrLen nCharLen )
     646                 :            : {
     647                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     648                 :            :     DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" );
     649                 :            : 
     650         [ -  + ]:      11798 :     if ( nCharLen == STRING_LEN )
     651                 :          0 :         nCharLen = ImplStringLen( pCharStr );
     652                 :            : 
     653                 :            : #ifdef DBG_UTIL
     654                 :            :     if ( DbgIsAssert() )
     655                 :            :     {
     656                 :            :         for ( xub_StrLen i = 0; i < nCharLen; i++ )
     657                 :            :         {
     658                 :            :             if ( !pCharStr[i] )
     659                 :            :             {
     660                 :            :                 OSL_FAIL( "String::Append() : nLen is wrong" );
     661                 :            :             }
     662                 :            :         }
     663                 :            :     }
     664                 :            : #endif
     665                 :            : 
     666                 :            :     // Catch overflow
     667                 :      11798 :     sal_Int32 nLen = mpData->mnLen;
     668                 :      11798 :     sal_Int32 nCopyLen = ImplGetCopyLen( nLen, nCharLen );
     669                 :            : 
     670         [ +  + ]:      11798 :     if ( nCopyLen )
     671                 :            :     {
     672                 :            :         // allocate string of new size
     673                 :      11008 :         STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );
     674                 :            : 
     675                 :            :         // copy string
     676                 :      11008 :         memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
     677                 :      11008 :         memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) );
     678                 :            : 
     679                 :            :         // free old string
     680                 :      11008 :         STRING_RELEASE((STRING_TYPE *)mpData);
     681                 :      11008 :         mpData = pNewData;
     682                 :            :     }
     683                 :            : 
     684                 :      11798 :     return *this;
     685                 :            : }
     686                 :            : 
     687                 :    4409848 : STRING& STRING::Append( STRCODE c )
     688                 :            : {
     689                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     690                 :            : 
     691                 :            :     // don't append null characters and keep string length < maxlen
     692                 :    4409848 :     sal_Int32 nLen = mpData->mnLen;
     693 [ +  - ][ +  - ]:    4409848 :     if ( c && (nLen < STRING_MAXLEN) )
     694                 :            :     {
     695                 :            :         // allocate string of new size
     696                 :    4409848 :         STRINGDATA* pNewData = ImplAllocData( nLen+1 );
     697                 :            : 
     698                 :            :         // copy string
     699                 :    4409848 :         memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
     700                 :    4409848 :         pNewData->maStr[nLen] = c;
     701                 :            : 
     702                 :            :         // free old string
     703                 :    4409848 :         STRING_RELEASE((STRING_TYPE *)mpData);
     704                 :    4409848 :         mpData = pNewData;
     705                 :            :     }
     706                 :            : 
     707                 :    4409848 :     return *this;
     708                 :            : }
     709                 :            : 
     710                 :      13965 : STRING& STRING::Assign( const STRCODE* pCharStr, xub_StrLen nLen )
     711                 :            : {
     712                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     713                 :            :     DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" );
     714                 :            : 
     715         [ -  + ]:      13965 :     if ( nLen == STRING_LEN )
     716                 :          0 :         nLen = ImplStringLen( pCharStr );
     717                 :            : 
     718                 :            : #ifdef DBG_UTIL
     719                 :            :     if ( DbgIsAssert() )
     720                 :            :     {
     721                 :            :         for ( xub_StrLen i = 0; i < nLen; i++ )
     722                 :            :         {
     723                 :            :             if ( !pCharStr[i] )
     724                 :            :             {
     725                 :            :                 OSL_FAIL( "String::Assign() : nLen is wrong" );
     726                 :            :             }
     727                 :            :         }
     728                 :            :     }
     729                 :            : #endif
     730                 :            : 
     731         [ -  + ]:      13965 :     if ( !nLen )
     732                 :            :     {
     733                 :          0 :         STRING_NEW((STRING_TYPE **)&mpData);
     734                 :            :     }
     735                 :            :     else
     736                 :            :     {
     737                 :            :         // copy without allocation if string length is identical
     738 [ +  + ][ +  - ]:      13965 :         if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
     739                 :       8823 :             memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
     740                 :            :         else
     741                 :            :         {
     742                 :            :             // free old string
     743                 :       5142 :             STRING_RELEASE((STRING_TYPE *)mpData);
     744                 :            : 
     745                 :            :             // allocate string of new size and copy
     746                 :       5142 :             mpData = ImplAllocData( nLen );
     747                 :       5142 :             memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
     748                 :            :         }
     749                 :            :     }
     750                 :            : 
     751                 :      13965 :     return *this;
     752                 :            : }
     753                 :            : 
     754                 :       5967 : STRING& STRING::Assign( STRCODE c )
     755                 :            : {
     756                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     757                 :            :     DBG_ASSERT( c, "String::Assign() - c is 0" );
     758                 :            : 
     759                 :            :     // initialize maintenance data
     760                 :       5967 :     STRING_RELEASE((STRING_TYPE *)mpData);
     761                 :       5967 :     mpData = ImplAllocData( 1 );
     762                 :       5967 :     mpData->maStr[0] = c;
     763                 :       5967 :     return *this;
     764                 :            : }
     765                 :            : 
     766                 :      20592 : xub_StrLen STRING::SearchAndReplace( const STRING& rStr, const STRING& rRepStr,
     767                 :            :                                      xub_StrLen nIndex )
     768                 :            : {
     769                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     770                 :            :     DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
     771                 :            :     DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );
     772                 :            : 
     773                 :      20592 :     xub_StrLen nSPos = Search( rStr, nIndex );
     774         [ +  + ]:      20592 :     if ( nSPos != STRING_NOTFOUND )
     775                 :      19992 :         Replace( nSPos, rStr.Len(), rRepStr );
     776                 :            : 
     777                 :      20592 :     return nSPos;
     778                 :            : }
     779                 :            : 
     780                 :        792 : static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2 )
     781                 :            : {
     782                 :            :     sal_Int32   nRet;
     783                 :            :     STRCODE     c1;
     784                 :            :     STRCODE     c2;
     785         [ +  + ]:        504 :     do
     786                 :            :     {
     787                 :            :         // Convert char if between 'A' and 'Z'
     788                 :        792 :         c1 = *pStr1;
     789                 :        792 :         c2 = *pStr2;
     790 [ +  + ][ +  - ]:        792 :         if ( (c1 >= 65) && (c1 <= 90) )
     791                 :        360 :             c1 += 32;
     792 [ +  + ][ +  - ]:        792 :         if ( (c2 >= 65) && (c2 <= 90) )
     793                 :        360 :             c2 += 32;
     794                 :        792 :         nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
     795         [ +  + ]:        792 :         if ( nRet != 0 )
     796                 :        288 :             break;
     797                 :            : 
     798                 :            :         ++pStr1,
     799                 :        504 :         ++pStr2;
     800                 :            :     }
     801                 :            :     while ( c2 );
     802                 :            : 
     803                 :        360 :     return nRet;
     804                 :            : }
     805                 :            : 
     806                 :        360 : sal_Bool STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr ) const
     807                 :            : {
     808                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     809                 :            : 
     810                 :        360 :     return (ImplStringICompare( mpData->maStr, pCharStr ) == 0);
     811                 :            : }
     812                 :            : 
     813                 :     146853 : STRING& STRING::Assign( const STRCODE* pCharStr )
     814                 :            : {
     815                 :            :     DBG_CHKTHIS( STRING, DBGCHECKSTRING );
     816                 :            :     DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" );
     817                 :            : 
     818                 :     146853 :     xub_StrLen nLen = ImplStringLen( pCharStr );
     819                 :            : 
     820         [ +  + ]:     146853 :     if ( !nLen )
     821                 :            :     {
     822                 :      68651 :         STRING_NEW((STRING_TYPE **)&mpData);
     823                 :            :     }
     824                 :            :     else
     825                 :            :     {
     826                 :            :         // copy without allocation if string length is identical
     827 [ +  + ][ +  + ]:      78202 :         if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
     828                 :         84 :             memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
     829                 :            :         else
     830                 :            :         {
     831                 :            :             // free old string
     832                 :      78118 :             STRING_RELEASE((STRING_TYPE *)mpData);
     833                 :            : 
     834                 :            :             // allocate string of new size and copy
     835                 :      78118 :             mpData = ImplAllocData( nLen );
     836                 :      78118 :             memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
     837                 :            :         }
     838                 :            :     }
     839                 :            : 
     840                 :     146853 :     return *this;
     841                 :            : }
     842                 :            : 
     843                 :   12288560 : xub_StrLen ImplStringLen( const sal_Char* pStr )
     844                 :            : {
     845                 :   12288560 :     const sal_Char* pTempStr = pStr;
     846         [ +  + ]:   83923088 :     while( *pTempStr )
     847                 :   71634528 :         ++pTempStr;
     848                 :   12288560 :     return (xub_StrLen)(pTempStr-pStr);
     849                 :            : }
     850                 :            : 
     851                 :     170168 : xub_StrLen ImplStringLen( const sal_Unicode* pStr )
     852                 :            : {
     853                 :     170168 :     const sal_Unicode* pTempStr = pStr;
     854         [ +  + ]:    1636395 :     while( *pTempStr )
     855                 :    1466227 :         ++pTempStr;
     856                 :     170168 :     return (xub_StrLen)(pTempStr-pStr);
     857                 :            : }
     858                 :            : 
     859                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10