LCOV - code coverage report
Current view: top level - sal/rtl/source - ustring.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 386 457 84.5 %
Date: 2012-08-25 Functions: 31 34 91.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 240 344 69.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "sal/config.h"
      30                 :            : 
      31                 :            : #if defined(_MSC_VER) && (_MSC_VER >= 1400)
      32                 :            : #pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance
      33                 :            : #endif
      34                 :            : 
      35                 :            : #include <cassert>
      36                 :            : #include <cstdlib>
      37                 :            : 
      38                 :            : #include <rtl/memory.h>
      39                 :            : #include <osl/diagnose.h>
      40                 :            : #include <osl/interlck.h>
      41                 :            : #include <rtl/alloc.h>
      42                 :            : #include <osl/mutex.h>
      43                 :            : #include <osl/doublecheckedlocking.h>
      44                 :            : #include <rtl/tencinfo.h>
      45                 :            : 
      46                 :            : #include <string.h>
      47                 :            : #include <sal/alloca.h>
      48                 :            : #include <sal/log.hxx>
      49                 :            : 
      50                 :            : #include "hash.hxx"
      51                 :            : #include "strimp.hxx"
      52                 :            : #include "surrogates.hxx"
      53                 :            : #include <rtl/ustring.h>
      54                 :            : 
      55                 :            : #include "rtl/math.h"
      56                 :            : #include "rtl/tencinfo.h"
      57                 :            : 
      58                 :            : /* ======================================================================= */
      59                 :            : 
      60                 :            : /* static data to be referenced by all empty strings
      61                 :            :  * the refCount is predefined to 1 and must never become 0 !
      62                 :            :  */
      63                 :            : static rtl_uString const aImplEmpty_rtl_uString =
      64                 :            : {
      65                 :            :     (sal_Int32) (SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32    refCount; */
      66                 :            :     0,                                               /*sal_Int32    length;   */
      67                 :            :     { 0 }                                            /*sal_Unicode  buffer[1];*/
      68                 :            : };
      69                 :            : 
      70                 :            : /* ======================================================================= */
      71                 :            : 
      72                 :            : #define IMPL_RTL_STRCODE            sal_Unicode
      73                 :            : #define IMPL_RTL_USTRCODE( c )      (c)
      74                 :            : #define IMPL_RTL_STRNAME( n )       rtl_ustr_ ## n
      75                 :            : 
      76                 :            : #define IMPL_RTL_STRINGNAME( n )    rtl_uString_ ## n
      77                 :            : #define IMPL_RTL_STRINGDATA         rtl_uString
      78                 :            : #define IMPL_RTL_EMPTYSTRING        aImplEmpty_rtl_uString
      79                 :            : #define IMPL_RTL_INTERN
      80                 :            : static void internRelease (rtl_uString *pThis);
      81                 :            : 
      82                 :            : /* ======================================================================= */
      83                 :            : 
      84                 :            : /* Include String/UString template code */
      85                 :            : 
      86                 :            : #include "strtmpl.cxx"
      87                 :            : 
      88                 :    5890191 : sal_Int32 rtl_ustr_indexOfAscii_WithLength(
      89                 :            :     sal_Unicode const * str, sal_Int32 len,
      90                 :            :     char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
      91                 :            : {
      92 [ +  - ][ +  + ]:    5890191 :     if (subLen > 0 && subLen <= len) {
      93                 :            :         sal_Int32 i;
      94         [ +  + ]:   23180809 :         for (i = 0; i <= len - subLen; ++i) {
      95         [ +  + ]:   20634894 :             if (rtl_ustr_asciil_reverseEquals_WithLength(
      96                 :   20634894 :                     str + i, subStr, subLen))
      97                 :            :             {
      98                 :      64905 :                 return i;
      99                 :            :             }
     100                 :            :         }
     101                 :            :     }
     102                 :    5890191 :     return -1;
     103                 :            : }
     104                 :            : 
     105                 :       5983 : sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength(
     106                 :            :     sal_Unicode const * str, sal_Int32 len,
     107                 :            :     char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
     108                 :            : {
     109 [ +  - ][ +  - ]:       5983 :     if (subLen > 0 && subLen <= len) {
     110                 :            :         sal_Int32 i;
     111         [ +  - ]:       5983 :         for (i = len - subLen; i >= 0; --i) {
     112         [ +  - ]:       5983 :             if (rtl_ustr_asciil_reverseEquals_WithLength(
     113                 :       5983 :                     str + i, subStr, subLen))
     114                 :            :             {
     115                 :       5983 :                 return i;
     116                 :            :             }
     117                 :            :         }
     118                 :            :     }
     119                 :       5983 :     return -1;
     120                 :            : }
     121                 :            : 
     122                 :          0 : sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f)
     123                 :            :     SAL_THROW_EXTERN_C()
     124                 :            : {
     125                 :          0 :     rtl_uString * pResult = NULL;
     126                 :            :     sal_Int32 nLen;
     127                 :            :     rtl_math_doubleToUString(
     128                 :            :         &pResult, 0, 0, f, rtl_math_StringFormat_G,
     129                 :            :         RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
     130                 :          0 :         0, sal_True);
     131                 :          0 :     nLen = pResult->length;
     132                 :            :     OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT);
     133                 :          0 :     memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
     134                 :          0 :     rtl_uString_release(pResult);
     135                 :          0 :     return nLen;
     136                 :            : }
     137                 :            : 
     138                 :      20010 : sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d)
     139                 :            :     SAL_THROW_EXTERN_C()
     140                 :            : {
     141                 :      20010 :     rtl_uString * pResult = NULL;
     142                 :            :     sal_Int32 nLen;
     143                 :            :     rtl_math_doubleToUString(
     144                 :            :         &pResult, 0, 0, d, rtl_math_StringFormat_G,
     145                 :            :         RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
     146                 :      20010 :         0, sal_True);
     147                 :      20010 :     nLen = pResult->length;
     148                 :            :     OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE);
     149                 :      20010 :     memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
     150                 :      20010 :     rtl_uString_release(pResult);
     151                 :      20010 :     return nLen;
     152                 :            : }
     153                 :            : 
     154                 :          0 : float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
     155                 :            : {
     156                 :            :     return (float) rtl_math_uStringToDouble(pStr,
     157                 :          0 :                                             pStr + rtl_ustr_getLength(pStr),
     158                 :          0 :                                             '.', 0, 0, 0);
     159                 :            : }
     160                 :            : 
     161                 :      10024 : double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
     162                 :            : {
     163                 :      10024 :     return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.',
     164                 :      10024 :                                     0, 0, 0);
     165                 :            : }
     166                 :            : 
     167                 :            : /* ======================================================================= */
     168                 :            : 
     169                 :      40888 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1,
     170                 :            :                                            const sal_Char* pStr2 )
     171                 :            :     SAL_THROW_EXTERN_C()
     172                 :            : {
     173                 :            :     sal_Int32 nRet;
     174 [ +  + ][ +  + ]:     351231 :     while ( ((nRet = ((sal_Int32)(*pStr1))-
                 [ +  + ]
     175                 :            :                      ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
     176                 :            :             *pStr2 )
     177                 :            :     {
     178                 :            :         /* Check ASCII range */
     179                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     180                 :            :                     "rtl_ustr_ascii_compare - Found char > 127" );
     181                 :     310343 :         pStr1++;
     182                 :     310343 :         pStr2++;
     183                 :            :     }
     184                 :            : 
     185                 :      40888 :     return nRet;
     186                 :            : }
     187                 :            : 
     188                 :            : /* ----------------------------------------------------------------------- */
     189                 :            : 
     190                 :   69495677 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1,
     191                 :            :                                                       sal_Int32 nStr1Len,
     192                 :            :                                                       const sal_Char* pStr2 )
     193                 :            :     SAL_THROW_EXTERN_C()
     194                 :            : {
     195                 :   69495677 :     sal_Int32 nRet = 0;
     196 [ +  + ][ +  + ]:  114092836 :     while( ((nRet = (nStr1Len ? (sal_Int32)(*pStr1) : 0)-
         [ +  + ][ +  + ]
                 [ +  + ]
     197                 :            :                     ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
     198                 :            :            nStr1Len && *pStr2 )
     199                 :            :     {
     200                 :            :         /* Check ASCII range */
     201                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     202                 :            :                     "rtl_ustr_ascii_compare_WithLength - Found char > 127" );
     203                 :   44597159 :         pStr1++;
     204                 :   44597159 :         pStr2++;
     205                 :   44597159 :         nStr1Len--;
     206                 :            :     }
     207                 :            : 
     208                 :   69495677 :     return nRet;
     209                 :            : }
     210                 :            : 
     211                 :            : /* ----------------------------------------------------------------------- */
     212                 :            : 
     213                 :    2152081 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1,
     214                 :            :                                                                sal_Int32 nStr1Len,
     215                 :            :                                                                const sal_Char* pStr2,
     216                 :            :                                                                sal_Int32 nShortenedLength )
     217                 :            :     SAL_THROW_EXTERN_C()
     218                 :            : {
     219                 :    2152081 :     const sal_Unicode*  pStr1End = pStr1 + nStr1Len;
     220                 :            :     sal_Int32           nRet;
     221 [ +  + ][ +  + ]:    5230463 :     while ( (nShortenedLength > 0) &&
         [ +  - ][ +  + ]
     222                 :            :             (pStr1 < pStr1End) && *pStr2 )
     223                 :            :     {
     224                 :            :         /* Check ASCII range */
     225                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     226                 :            :                     "rtl_ustr_ascii_shortenedCompare_WithLength - Found char > 127" );
     227                 :            : 
     228                 :            :         nRet = ((sal_Int32)*pStr1)-
     229                 :    4785634 :                ((sal_Int32)(unsigned char)*pStr2);
     230         [ +  + ]:    4785634 :         if ( nRet != 0 )
     231                 :    1707252 :             return nRet;
     232                 :            : 
     233                 :    3078382 :         nShortenedLength--;
     234                 :    3078382 :         pStr1++;
     235                 :    3078382 :         pStr2++;
     236                 :            :     }
     237                 :            : 
     238         [ +  + ]:     444829 :     if ( nShortenedLength <= 0 )
     239                 :     314028 :         return 0;
     240                 :            : 
     241         [ +  - ]:     130801 :     if ( *pStr2 )
     242                 :            :     {
     243                 :            :         OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
     244                 :            :         // first is a substring of the second string => less (negative value)
     245                 :     130801 :         nRet = -1;
     246                 :            :     }
     247                 :            :     else
     248                 :            :     {
     249                 :            :         // greater or equal
     250                 :          0 :         nRet = pStr1End - pStr1;
     251                 :            :     }
     252                 :            : 
     253                 :    2152081 :     return nRet;
     254                 :            : }
     255                 :            : 
     256                 :            : /* ----------------------------------------------------------------------- */
     257                 :            : 
     258                 :     751743 : sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1,
     259                 :            :                                                               sal_Int32 nStr1Len,
     260                 :            :                                                               const sal_Char* pStr2,
     261                 :            :                                                               sal_Int32 nStr2Len )
     262                 :            :     SAL_THROW_EXTERN_C()
     263                 :            : {
     264                 :     751743 :     const sal_Unicode*  pStr1Run = pStr1+nStr1Len;
     265                 :     751743 :     const sal_Char*     pStr2Run = pStr2+nStr2Len;
     266                 :            :     sal_Int32           nRet;
     267 [ +  + ][ +  - ]:    1458000 :     while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
                 [ +  + ]
     268                 :            :     {
     269                 :            :         /* Check ASCII range */
     270                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     271                 :            :                     "rtl_ustr_asciil_reverseCompare_WithLength - Found char > 127" );
     272                 :    1455623 :         pStr1Run--;
     273                 :    1455623 :         pStr2Run--;
     274                 :    1455623 :         nRet = ((sal_Int32)*pStr1Run)-((sal_Int32)*pStr2Run);
     275         [ +  + ]:    1455623 :         if ( nRet )
     276                 :     749366 :             return nRet;
     277                 :            :     }
     278                 :            : 
     279                 :     751743 :     return nStr1Len - nStr2Len;
     280                 :            : }
     281                 :            : 
     282                 :            : /* ----------------------------------------------------------------------- */
     283                 :            : 
     284                 :   37066145 : sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1,
     285                 :            :                                                               const sal_Char* pStr2,
     286                 :            :                                                               sal_Int32 nStrLen )
     287                 :            :     SAL_THROW_EXTERN_C()
     288                 :            : {
     289                 :   37066145 :     const sal_Unicode*  pStr1Run = pStr1+nStrLen;
     290                 :   37066145 :     const sal_Char*     pStr2Run = pStr2+nStrLen;
     291         [ +  + ]:  168352960 :     while ( pStr1 < pStr1Run )
     292                 :            :     {
     293                 :            :         /* Check ASCII range */
     294                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     295                 :            :                     "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
     296                 :  155591683 :         pStr1Run--;
     297                 :  155591683 :         pStr2Run--;
     298         [ +  + ]:  155591683 :         if( *pStr1Run != (sal_Unicode)*pStr2Run )
     299                 :   24304868 :             return sal_False;
     300                 :            :     }
     301                 :            : 
     302                 :   37066145 :     return sal_True;
     303                 :            : }
     304                 :            : 
     305                 :            : /* ----------------------------------------------------------------------- */
     306                 :            : 
     307                 :          0 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1,
     308                 :            :                                                           const sal_Char* pStr2 )
     309                 :            :     SAL_THROW_EXTERN_C()
     310                 :            : {
     311                 :            :     sal_Int32   nRet;
     312                 :            :     sal_Int32   c1;
     313                 :            :     sal_Int32   c2;
     314         [ #  # ]:          0 :     do
     315                 :            :     {
     316                 :            :         /* Check ASCII range */
     317                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     318                 :            :                     "rtl_ustr_ascii_compareIgnoreAsciiCase - Found char > 127" );
     319                 :            :         /* If character between 'A' and 'Z', than convert it to lowercase */
     320                 :          0 :         c1 = (sal_Int32)*pStr1;
     321                 :          0 :         c2 = (sal_Int32)((unsigned char)*pStr2);
     322 [ #  # ][ #  # ]:          0 :         if ( (c1 >= 65) && (c1 <= 90) )
     323                 :          0 :             c1 += 32;
     324 [ #  # ][ #  # ]:          0 :         if ( (c2 >= 65) && (c2 <= 90) )
     325                 :          0 :             c2 += 32;
     326                 :          0 :         nRet = c1-c2;
     327         [ #  # ]:          0 :         if ( nRet != 0 )
     328                 :          0 :             return nRet;
     329                 :            : 
     330                 :          0 :         pStr1++;
     331                 :          0 :         pStr2++;
     332                 :            :     }
     333                 :            :     while ( c2 );
     334                 :            : 
     335                 :          0 :     return 0;
     336                 :            : }
     337                 :            : 
     338                 :            : /* ----------------------------------------------------------------------- */
     339                 :            : 
     340                 :    8401136 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
     341                 :            :                                                                      sal_Int32 nStr1Len,
     342                 :            :                                                                      const sal_Char* pStr2 )
     343                 :            :     SAL_THROW_EXTERN_C()
     344                 :            : {
     345                 :            :     sal_Int32   nRet;
     346                 :            :     sal_Int32   c1;
     347                 :            :     sal_Int32   c2;
     348         [ +  - ]:    6368385 :     do
     349                 :            :     {
     350                 :            :         /* Check ASCII range */
     351                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     352                 :            :                     "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength - Found char > 127" );
     353         [ +  + ]:    8401136 :         if ( !nStr1Len )
     354         [ +  + ]:     747571 :             return *pStr2 == '\0' ? 0 : -1;
     355                 :            : 
     356                 :            :         /* If character between 'A' and 'Z', than convert it to lowercase */
     357                 :    7653565 :         c1 = (sal_Int32)*pStr1;
     358                 :    7653565 :         c2 = (sal_Int32)((unsigned char)*pStr2);
     359 [ +  + ][ +  + ]:    7653565 :         if ( (c1 >= 65) && (c1 <= 90) )
     360                 :    1147395 :             c1 += 32;
     361 [ +  + ][ +  + ]:    7653565 :         if ( (c2 >= 65) && (c2 <= 90) )
     362                 :     320450 :             c2 += 32;
     363                 :    7653565 :         nRet = c1-c2;
     364         [ +  + ]:    7653565 :         if ( nRet != 0 )
     365                 :    1285180 :             return nRet;
     366                 :            : 
     367                 :    6368385 :         pStr1++;
     368                 :    6368385 :         pStr2++;
     369                 :    6368385 :         nStr1Len--;
     370                 :            :     }
     371                 :            :     while( c2 );
     372                 :            : 
     373                 :    2032751 :     return 0;
     374                 :            : }
     375                 :            : 
     376                 :    2163706 : sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
     377                 :            :     sal_Unicode const * first, sal_Int32 firstLen,
     378                 :            :     char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C()
     379                 :            : {
     380                 :            :     sal_Int32 i;
     381         [ -  + ]:    2163706 :     sal_Int32 len = firstLen < secondLen ? firstLen : secondLen;
     382         [ +  + ]:    7083077 :     for (i = 0; i < len; ++i) {
     383                 :            :         /* Check ASCII range */
     384                 :            :         SAL_WARN_IF( ((unsigned char)*second) > 127, "rtl.string",
     385                 :            :                     "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths - Found char > 127" );
     386                 :    5872863 :         sal_Int32 c1 = *first++;
     387                 :    5872863 :         sal_Int32 c2 = (unsigned char) *second++;
     388                 :            :         sal_Int32 d;
     389 [ +  + ][ +  + ]:    5872863 :         if (c1 >= 65 && c1 <= 90) {
     390                 :     233768 :             c1 += 32;
     391                 :            :         }
     392 [ +  + ][ +  + ]:    5872863 :         if (c2 >= 65 && c2 <= 90) {
     393                 :        328 :             c2 += 32;
     394                 :            :         }
     395                 :    5872863 :         d = c1 - c2;
     396         [ +  + ]:    5872863 :         if (d != 0) {
     397                 :     953492 :             return d;
     398                 :            :         }
     399                 :            :     }
     400                 :    2163706 :     return firstLen - secondLen;
     401                 :            : }
     402                 :            : 
     403                 :            : /* ----------------------------------------------------------------------- */
     404                 :            : 
     405                 :      22698 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
     406                 :            :                                                                               sal_Int32 nStr1Len,
     407                 :            :                                                                               const sal_Char* pStr2,
     408                 :            :                                                                               sal_Int32 nShortenedLength )
     409                 :            :     SAL_THROW_EXTERN_C()
     410                 :            : {
     411                 :      22698 :     const sal_Unicode*  pStr1End = pStr1 + nStr1Len;
     412                 :            :     sal_Int32           nRet;
     413                 :            :     sal_Int32           c1;
     414                 :            :     sal_Int32           c2;
     415 [ +  + ][ +  + ]:     526438 :     while ( (nShortenedLength > 0) &&
         [ +  - ][ +  + ]
     416                 :            :             (pStr1 < pStr1End) && *pStr2 )
     417                 :            :     {
     418                 :            :         /* Check ASCII range */
     419                 :            :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     420                 :            :                     "rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength - Found char > 127" );
     421                 :            : 
     422                 :            :         /* If character between 'A' and 'Z', than convert it to lowercase */
     423                 :     524863 :         c1 = (sal_Int32)*pStr1;
     424                 :     524863 :         c2 = (sal_Int32)((unsigned char)*pStr2);
     425 [ +  + ][ +  + ]:     524863 :         if ( (c1 >= 65) && (c1 <= 90) )
     426                 :        139 :             c1 += 32;
     427 [ +  + ][ +  + ]:     524863 :         if ( (c2 >= 65) && (c2 <= 90) )
     428                 :        292 :             c2 += 32;
     429                 :     524863 :         nRet = c1-c2;
     430         [ +  + ]:     524863 :         if ( nRet != 0 )
     431                 :      21123 :             return nRet;
     432                 :            : 
     433                 :     503740 :         nShortenedLength--;
     434                 :     503740 :         pStr1++;
     435                 :     503740 :         pStr2++;
     436                 :            :     }
     437                 :            : 
     438         [ +  + ]:       1575 :     if ( nShortenedLength <= 0 )
     439                 :       1465 :         return 0;
     440                 :            : 
     441         [ +  - ]:        110 :     if ( *pStr2 )
     442                 :            :     {
     443                 :            :         OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
     444                 :            :         // first is a substring of the second string => less (negative value)
     445                 :        110 :         nRet = -1;
     446                 :            :     }
     447                 :            :     else
     448                 :            :     {
     449                 :            :         // greater or equal
     450                 :          0 :         nRet = pStr1End - pStr1;
     451                 :            :     }
     452                 :            : 
     453                 :      22698 :     return nRet;
     454                 :            : }
     455                 :            : 
     456                 :            : /* ----------------------------------------------------------------------- */
     457                 :            : 
     458                 :    6674902 : void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis,
     459                 :            :                                         const sal_Char* pCharStr )
     460                 :            :     SAL_THROW_EXTERN_C()
     461                 :            : {
     462                 :            :     sal_Int32 nLen;
     463                 :            : 
     464         [ +  + ]:    6674902 :     if ( pCharStr )
     465                 :            :     {
     466                 :    6674822 :         const sal_Char* pTempStr = pCharStr;
     467         [ +  + ]:   68474300 :         while( *pTempStr )
     468                 :   61799478 :             pTempStr++;
     469                 :    6674822 :         nLen = pTempStr-pCharStr;
     470                 :            :     }
     471                 :            :     else
     472                 :         80 :         nLen = 0;
     473                 :            : 
     474         [ +  + ]:    6674902 :     if ( !nLen )
     475                 :            :     {
     476                 :      31974 :         IMPL_RTL_STRINGNAME( new )( ppThis );
     477                 :    6674905 :         return;
     478                 :            :     }
     479                 :            : 
     480         [ +  + ]:    6642928 :     if ( *ppThis )
     481                 :      11301 :         IMPL_RTL_STRINGNAME( release )( *ppThis );
     482                 :            : 
     483                 :    6642928 :     *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
     484                 :            :     OSL_ASSERT(*ppThis != NULL);
     485         [ +  - ]:    6642931 :     if ( (*ppThis) )
     486                 :            :     {
     487                 :    6642931 :         IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
     488         [ +  + ]:   61799739 :         do
     489                 :            :         {
     490                 :            :             /* Check ASCII range */
     491                 :            :             SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string",
     492                 :            :                         "rtl_uString_newFromAscii - Found char > 127" );
     493                 :            : 
     494                 :   61799739 :             *pBuffer = *pCharStr;
     495                 :   61799739 :             pBuffer++;
     496                 :   61799739 :             pCharStr++;
     497                 :            :         }
     498                 :            :         while ( *pCharStr );
     499                 :            :     }
     500                 :            : 
     501                 :            :     RTL_LOG_STRING_NEW( *ppThis );
     502                 :            : }
     503                 :            : 
     504                 :      27878 : void SAL_CALL rtl_uString_newFromCodePoints(
     505                 :            :     rtl_uString ** newString, sal_uInt32 const * codePoints,
     506                 :            :     sal_Int32 codePointCount) SAL_THROW_EXTERN_C()
     507                 :            : {
     508                 :            :     sal_Int32 n;
     509                 :            :     sal_Int32 i;
     510                 :            :     sal_Unicode * p;
     511                 :            :     OSL_ASSERT(
     512                 :            :         newString != NULL &&
     513                 :            :         (codePoints != NULL || codePointCount == 0) &&
     514                 :            :         codePointCount >= 0);
     515         [ +  + ]:      27878 :     if (codePointCount == 0) {
     516                 :      13183 :         rtl_uString_new(newString);
     517                 :      13183 :         return;
     518                 :            :     }
     519         [ -  + ]:      14695 :     if (*newString != NULL) {
     520                 :          0 :         rtl_uString_release(*newString);
     521                 :            :     }
     522                 :      14695 :     n = codePointCount;
     523         [ +  + ]:      29395 :     for (i = 0; i < codePointCount; ++i) {
     524                 :            :         OSL_ASSERT(codePoints[i] <= 0x10FFFF);
     525         [ +  + ]:      14700 :         if (codePoints[i] >= 0x10000) {
     526                 :         10 :             ++n;
     527                 :            :         }
     528                 :            :     }
     529                 :            :     /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
     530                 :            :        representation with wrap around (the necessary number of UTF-16 code
     531                 :            :        units will be no larger than 2 * SAL_MAX_INT32, represented as
     532                 :            :        sal_Int32 -2): */
     533         [ -  + ]:      14695 :     if (n < 0) {
     534                 :          0 :         *newString = NULL;
     535                 :          0 :         return;
     536                 :            :     }
     537                 :      14695 :     *newString = rtl_uString_ImplAlloc(n);
     538         [ -  + ]:      14695 :     if (*newString == NULL) {
     539                 :          0 :         return;
     540                 :            :     }
     541                 :      14695 :     p = (*newString)->buffer;
     542         [ +  + ]:      42578 :     for (i = 0; i < codePointCount; ++i) {
     543                 :      14700 :         sal_uInt32 c = codePoints[i];
     544         [ +  + ]:      14700 :         if (c < 0x10000) {
     545                 :      14690 :             *p++ = (sal_Unicode) c;
     546                 :            :         } else {
     547                 :         10 :             c -= 0x10000;
     548                 :         10 :             *p++ = (sal_Unicode) ((c >> 10) | SAL_RTL_FIRST_HIGH_SURROGATE);
     549                 :         10 :             *p++ = (sal_Unicode) ((c & 0x3FF) | SAL_RTL_FIRST_LOW_SURROGATE);
     550                 :            :         }
     551                 :            :     }
     552                 :            :     RTL_LOG_STRING_NEW( *newString );
     553                 :            : }
     554                 :            : 
     555                 :            : /* ======================================================================= */
     556                 :            : 
     557                 :   27672958 : static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen )
     558                 :            : {
     559                 :            :     int             n;
     560                 :            :     sal_uChar       c;
     561                 :            :     const sal_Char* pEndStr;
     562                 :            : 
     563                 :   27672958 :     n = 0;
     564                 :   27672958 :     pEndStr  = pStr+nLen;
     565         [ +  + ]:  457659753 :     while ( pStr < pEndStr )
     566                 :            :     {
     567                 :  429986795 :         c = (sal_uChar)*pStr;
     568                 :            : 
     569         [ +  + ]:  429986795 :         if ( !(c & 0x80) )
     570                 :  427130398 :             pStr++;
     571         [ +  + ]:    2856397 :         else if ( (c & 0xE0) == 0xC0 )
     572                 :     232519 :             pStr += 2;
     573         [ +  - ]:    2623878 :         else if ( (c & 0xF0) == 0xE0 )
     574                 :    2623878 :             pStr += 3;
     575         [ #  # ]:          0 :         else if ( (c & 0xF8) == 0xF0 )
     576                 :          0 :             pStr += 4;
     577         [ #  # ]:          0 :         else if ( (c & 0xFC) == 0xF8 )
     578                 :          0 :             pStr += 5;
     579         [ #  # ]:          0 :         else if ( (c & 0xFE) == 0xFC )
     580                 :          0 :             pStr += 6;
     581                 :            :         else
     582                 :          0 :             pStr++;
     583                 :            : 
     584                 :  429986795 :         n++;
     585                 :            :     }
     586                 :            : 
     587                 :   27672958 :     return n;
     588                 :            : }
     589                 :            : 
     590                 :            : /* ----------------------------------------------------------------------- */
     591                 :            : 
     592                 :   47773063 : static void rtl_string2UString_status( rtl_uString** ppThis,
     593                 :            :                                        const sal_Char* pStr,
     594                 :            :                                        sal_Int32 nLen,
     595                 :            :                                        rtl_TextEncoding eTextEncoding,
     596                 :            :                                        sal_uInt32 nCvtFlags,
     597                 :            :                                        sal_uInt32 *pInfo )
     598                 :            : {
     599                 :            :     OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding),
     600                 :            :                "rtl_string2UString_status() - Wrong TextEncoding" );
     601                 :            : 
     602         [ +  + ]:   47773063 :     if ( !nLen )
     603                 :            :     {
     604                 :    1082499 :         rtl_uString_new( ppThis );
     605         [ +  + ]:    1082499 :         if (pInfo != NULL) {
     606                 :     837964 :             *pInfo = 0;
     607                 :            :         }
     608                 :            :     }
     609                 :            :     else
     610                 :            :     {
     611         [ +  + ]:   46690564 :         if ( *ppThis )
     612                 :     506373 :             IMPL_RTL_STRINGNAME( release )( *ppThis );
     613                 :            : 
     614                 :            :         /* Optimization for US-ASCII */
     615         [ +  + ]:   46690576 :         if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
     616                 :            :         {
     617                 :            :             IMPL_RTL_STRCODE* pBuffer;
     618                 :   18784042 :             *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
     619         [ -  + ]:   18784043 :             if (*ppThis == NULL) {
     620         [ #  # ]:          0 :                 if (pInfo != NULL) {
     621                 :            :                     *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     622                 :          0 :                         RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     623                 :            :                 }
     624                 :          0 :                 return;
     625                 :            :             }
     626                 :   18784043 :             pBuffer = (*ppThis)->buffer;
     627         [ +  + ]:  297016148 :             do
     628                 :            :             {
     629                 :            :                 /* Check ASCII range */
     630                 :            :                 SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
     631                 :            :                             "rtl_string2UString_status() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
     632                 :            : 
     633                 :  297016148 :                 *pBuffer = *pStr;
     634                 :  297016148 :                 pBuffer++;
     635                 :  297016148 :                 pStr++;
     636                 :  297016148 :                 nLen--;
     637                 :            :             }
     638                 :            :             while ( nLen );
     639         [ -  + ]:   18784043 :             if (pInfo != NULL) {
     640                 :          0 :                 *pInfo = 0;
     641                 :            :             }
     642                 :            :         }
     643                 :            :         else
     644                 :            :         {
     645                 :            :             rtl_uString*                pTemp;
     646                 :   27906534 :             rtl_uString*                pTemp2 = NULL;
     647                 :            :             rtl_TextToUnicodeConverter  hConverter;
     648                 :            :             sal_uInt32                  nInfo;
     649                 :            :             sal_Size                    nSrcBytes;
     650                 :            :             sal_Size                    nDestChars;
     651                 :            :             sal_Size                    nNewLen;
     652                 :            : 
     653                 :            :             /* Optimization for UTF-8 - we try to calculate the exact length */
     654                 :            :             /* For all other encoding we try the maximum - and reallocate
     655                 :            :                the buffer if needed */
     656         [ +  + ]:   27906534 :             if ( eTextEncoding == RTL_TEXTENCODING_UTF8 )
     657                 :            :             {
     658                 :   27672958 :                 nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen );
     659                 :            :                 /* Includes the string only ASCII, then we could copy
     660                 :            :                    the buffer faster */
     661         [ +  + ]:   27672958 :                 if ( nNewLen == (sal_Size)nLen )
     662                 :            :                 {
     663                 :            :                     IMPL_RTL_STRCODE* pBuffer;
     664         [ +  - ]:   26830558 :                     *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
     665         [ -  + ]:   26830559 :                     if (*ppThis == NULL)
     666                 :            :                     {
     667         [ #  # ]:          0 :                         if (pInfo != NULL) {
     668                 :            :                             *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     669                 :          0 :                                 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     670                 :            :                         }
     671                 :            :                         return;
     672                 :            :                     }
     673                 :   26830559 :                     pBuffer = (*ppThis)->buffer;
     674         [ +  + ]:  413966802 :                     do
     675                 :            :                     {
     676                 :            :                         /* Check ASCII range */
     677                 :            :                         SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
     678                 :            :                                     "rtl_string2UString_status() - UTF8 test encoding is wrong" );
     679                 :            : 
     680                 :  413966802 :                         *pBuffer = *pStr;
     681                 :  413966802 :                         pBuffer++;
     682                 :  413966802 :                         pStr++;
     683                 :  413966802 :                         nLen--;
     684                 :            :                     }
     685                 :            :                     while ( nLen );
     686         [ +  + ]:   26830559 :                     if (pInfo != NULL) {
     687                 :   17840887 :                         *pInfo = 0;
     688                 :            :                     }
     689                 :            :                     RTL_LOG_STRING_NEW( *ppThis );
     690                 :            :                     return;
     691                 :            :                 }
     692                 :            :             }
     693                 :            :             else
     694                 :     233576 :                 nNewLen = nLen;
     695                 :            : 
     696                 :    1075976 :             nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH;
     697         [ +  - ]:    1075976 :             hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
     698                 :            : 
     699         [ +  - ]:    1075975 :             pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
     700         [ -  + ]:    1075975 :             if (pTemp == NULL) {
     701         [ #  # ]:          0 :                 if (pInfo != NULL) {
     702                 :            :                     *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     703                 :          0 :                         RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     704                 :            :                 }
     705                 :            :                 return;
     706                 :            :             }
     707                 :            :             nDestChars = rtl_convertTextToUnicode( hConverter, 0,
     708                 :            :                                                    pStr, nLen,
     709                 :            :                                                    pTemp->buffer, nNewLen,
     710                 :            :                                                    nCvtFlags,
     711         [ +  - ]:    1075975 :                                                    &nInfo, &nSrcBytes );
     712                 :            : 
     713                 :            :             /* Buffer not big enough, try again with enough space */
     714                 :            :             /* Shouldn't be the case, but if we get textencoding which
     715                 :            :                could results in more unicode characters we have this
     716                 :            :                code here. Could be the case for apple encodings */
     717         [ +  + ]:    1076255 :             while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL )
     718                 :            :             {
     719                 :        280 :                 rtl_freeMemory( pTemp );
     720                 :        280 :                 nNewLen += 8;
     721         [ +  - ]:        280 :                 pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
     722         [ -  + ]:        280 :                 if (pTemp == NULL) {
     723         [ #  # ]:          0 :                     if (pInfo != NULL) {
     724                 :            :                         *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     725                 :          0 :                             RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     726                 :            :                     }
     727                 :            :                     return;
     728                 :            :                 }
     729                 :            :                 nDestChars = rtl_convertTextToUnicode( hConverter, 0,
     730                 :            :                                                        pStr, nLen,
     731                 :            :                                                        pTemp->buffer, nNewLen,
     732                 :            :                                                        nCvtFlags,
     733         [ +  - ]:        280 :                                                        &nInfo, &nSrcBytes );
     734                 :            :             }
     735                 :            : 
     736         [ +  + ]:    1075975 :             if (pInfo)
     737                 :     203089 :                 *pInfo = nInfo;
     738                 :            : 
     739                 :            :             /* Set the buffer to the correct size or if there is too
     740                 :            :                much overhead, reallocate to the correct size */
     741         [ -  + ]:    1075975 :             if ( nNewLen > nDestChars+8 )
     742                 :            :             {
     743         [ #  # ]:          0 :                 pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )( nDestChars );
     744                 :            :             }
     745         [ -  + ]:    1075975 :             if (pTemp2 != NULL)
     746                 :            :             {
     747         [ #  # ]:          0 :                 rtl_str_ImplCopy(pTemp2->buffer, pTemp->buffer, nDestChars);
     748                 :          0 :                 rtl_freeMemory(pTemp);
     749                 :          0 :                 pTemp = pTemp2;
     750                 :            :             }
     751                 :            :             else
     752                 :            :             {
     753                 :    1075975 :                 pTemp->length = nDestChars;
     754                 :    1075975 :                 pTemp->buffer[nDestChars] = 0;
     755                 :            :             }
     756                 :            : 
     757         [ +  - ]:    1075975 :             rtl_destroyTextToUnicodeConverter( hConverter );
     758                 :    1075975 :             *ppThis = pTemp;
     759                 :            : 
     760                 :            :             /* Results the conversion in an empty buffer -
     761                 :            :                create an empty string */
     762 [ +  - ][ +  + ]:    1075975 :             if ( pTemp && !nDestChars )
     763                 :   47773076 :                 rtl_uString_new( ppThis );
     764                 :            :         }
     765                 :            :     }
     766                 :            :     RTL_LOG_STRING_NEW( *ppThis );
     767                 :            : }
     768                 :            : 
     769                 :   28558180 : void SAL_CALL rtl_string2UString( rtl_uString** ppThis,
     770                 :            :                                   const sal_Char* pStr,
     771                 :            :                                   sal_Int32 nLen,
     772                 :            :                                   rtl_TextEncoding eTextEncoding,
     773                 :            :                                   sal_uInt32 nCvtFlags ) SAL_THROW_EXTERN_C()
     774                 :            : {
     775                 :            :     rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding,
     776                 :   28558180 :                                nCvtFlags, NULL );
     777                 :   28558187 : }
     778                 :            : 
     779                 :            : /* ----------------------------------------------------------------------- */
     780                 :            : 
     781                 :            : enum StrLifecycle {
     782                 :            :     CANNOT_RETURN,
     783                 :            :     CAN_RETURN = 1
     784                 :            : };
     785                 :            : 
     786                 :            : static oslMutex
     787                 :     740019 : getInternMutex()
     788                 :            : {
     789                 :            :     static oslMutex pPoolGuard = NULL;
     790         [ +  + ]:     740019 :     if( !pPoolGuard )
     791                 :            :     {
     792                 :            :         oslMutex pGlobalGuard;
     793                 :        271 :         pGlobalGuard = *osl_getGlobalMutex();
     794                 :        271 :         osl_acquireMutex( pGlobalGuard );
     795         [ +  - ]:        271 :         if( !pPoolGuard )
     796                 :            :         {
     797                 :        271 :             oslMutex p = osl_createMutex();
     798                 :            :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     799                 :        271 :             pPoolGuard = p;
     800                 :            :         }
     801                 :        271 :         osl_releaseMutex( pGlobalGuard );
     802                 :            :     }
     803                 :            :     else
     804                 :            :     {
     805                 :            :         OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     806                 :            :     }
     807                 :            : 
     808                 :     740019 :     return pPoolGuard;
     809                 :            : }
     810                 :            : 
     811                 :            : /* returns true if we found a dup in the pool */
     812                 :     407324 : static void rtl_ustring_intern_internal( rtl_uString ** newStr,
     813                 :            :                                          rtl_uString  * str,
     814                 :            :                                          StrLifecycle   can_return )
     815                 :            : {
     816                 :            :     oslMutex pPoolMutex;
     817                 :            : 
     818                 :     407324 :     pPoolMutex = getInternMutex();
     819                 :            : 
     820                 :     407324 :     osl_acquireMutex( pPoolMutex );
     821                 :            : 
     822                 :     407324 :     *newStr = rtl_str_hash_intern (str, can_return);
     823                 :            : 
     824                 :     407324 :     osl_releaseMutex( pPoolMutex );
     825                 :            : 
     826 [ +  + ][ +  + ]:     407324 :     if( can_return && *newStr != str )
     827                 :            :     { /* we dupped, then found a match */
     828                 :      47007 :         rtl_freeMemory( str );
     829                 :            :     }
     830                 :     407324 : }
     831                 :            : 
     832                 :      53050 : void SAL_CALL rtl_uString_intern( rtl_uString ** newStr,
     833                 :            :                                   rtl_uString  * str) SAL_THROW_EXTERN_C()
     834                 :            : {
     835         [ +  + ]:      53050 :     if (SAL_STRING_IS_INTERN(str))
     836                 :            :     {
     837         [ +  - ]:       1082 :         IMPL_RTL_AQUIRE( str );
     838                 :       1082 :         *newStr = str;
     839                 :            :     }
     840                 :            :     else
     841                 :            :     {
     842                 :      51968 :         rtl_uString *pOrg = *newStr;
     843                 :      51968 :         *newStr = NULL;
     844                 :      51968 :         rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN );
     845         [ -  + ]:      51968 :         if (pOrg)
     846                 :          0 :             rtl_uString_release (pOrg);
     847                 :            :     }
     848                 :      53050 : }
     849                 :            : 
     850                 :     332948 : static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding )
     851                 :            : {
     852                 :            :     // FIXME: Maybe we should use a bit flag in the higher bits of the
     853                 :            :     // eTextEncoding value itself to determine the encoding type.  But if we
     854                 :            :     // do, be sure to mask the value in certain places that expect the values
     855                 :            :     // to be numbered serially from 0 and up.  One such place is
     856                 :            :     // Impl_getTextEncodingData().
     857                 :            : 
     858         [ -  + ]:     332948 :     switch ( eTextEncoding )
     859                 :            :     {
     860                 :            :         // 1 to 1 (with no zero elements)
     861                 :            :         case RTL_TEXTENCODING_IBM_437:
     862                 :            :         case RTL_TEXTENCODING_IBM_850:
     863                 :            :         case RTL_TEXTENCODING_IBM_860:
     864                 :            :         case RTL_TEXTENCODING_IBM_861:
     865                 :            :         case RTL_TEXTENCODING_IBM_863:
     866                 :            :         case RTL_TEXTENCODING_IBM_865:
     867                 :          0 :             return len;
     868                 :            :         break;
     869                 :            :     }
     870                 :     332948 :     return 0;
     871                 :            : }
     872                 :            : 
     873                 :     355356 : void SAL_CALL rtl_uString_internConvert( rtl_uString   ** newStr,
     874                 :            :                                          const sal_Char * str,
     875                 :            :                                          sal_Int32        len,
     876                 :            :                                          rtl_TextEncoding eTextEncoding,
     877                 :            :                                          sal_uInt32       convertFlags,
     878                 :            :                                          sal_uInt32     * pInfo )
     879                 :            :     SAL_THROW_EXTERN_C()
     880                 :            : {
     881                 :            :     rtl_uString *scratch;
     882                 :            : 
     883         [ -  + ]:     355356 :     if (*newStr)
     884                 :            :     {
     885                 :          0 :         rtl_uString_release (*newStr);
     886                 :          0 :         *newStr = NULL;
     887                 :            :     }
     888                 :            : 
     889         [ +  - ]:     355356 :     if ( len < 256 )
     890                 :            :     { // try various optimisations
     891                 :            :         sal_Int32 ulen;
     892         [ -  + ]:     355356 :         if ( len < 0 )
     893                 :          0 :             len = strlen( str );
     894         [ +  + ]:     355356 :         if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
     895                 :            :         {
     896                 :            :             int i;
     897                 :            :             rtl_uString *pScratch;
     898                 :            :             pScratch = static_cast< rtl_uString * >(
     899                 :      22408 :                 alloca(sizeof (rtl_uString) + len * sizeof (IMPL_RTL_STRCODE)));
     900         [ +  + ]:     512220 :             for (i = 0; i < len; i++)
     901                 :            :             {
     902                 :            :                 /* Check ASCII range */
     903                 :            :                 SAL_WARN_IF( ((unsigned char)str[i]) > 127, "rtl.string",
     904                 :            :                             "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
     905                 :     489812 :                 pScratch->buffer[i] = str[i];
     906                 :            :             }
     907                 :      22408 :             pScratch->length = len;
     908         [ +  - ]:      22408 :             rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
     909                 :            :             return;
     910                 :            :         }
     911         [ -  + ]:     332948 :         else if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 )
     912                 :            :         {
     913                 :            :             rtl_uString *pScratch;
     914                 :            :             rtl_TextToUnicodeConverter hConverter;
     915                 :            :             sal_Size nSrcBytes;
     916                 :            :             sal_uInt32 nInfo;
     917                 :            : 
     918                 :            :             pScratch = static_cast< rtl_uString * >(
     919                 :          0 :                 alloca(
     920                 :          0 :                     sizeof (rtl_uString) + ulen * sizeof (IMPL_RTL_STRCODE)));
     921                 :            : 
     922         [ #  # ]:          0 :             hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
     923                 :            :             rtl_convertTextToUnicode(
     924         [ #  # ]:          0 :                 hConverter, 0, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes );
     925         [ #  # ]:          0 :             rtl_destroyTextToUnicodeConverter( hConverter );
     926                 :            : 
     927         [ #  # ]:          0 :             if (pInfo)
     928                 :          0 :                 *pInfo = nInfo;
     929                 :            : 
     930                 :          0 :             pScratch->length = ulen;
     931         [ #  # ]:          0 :             rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
     932                 :            :             return;
     933                 :            :         }
     934                 :            : 
     935                 :            :         /* FIXME: we want a nice UTF-8 / alloca shortcut here */
     936                 :            :     }
     937                 :            : 
     938                 :     332948 :     scratch = NULL;
     939                 :            :     rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags,
     940         [ +  - ]:     332948 :                                pInfo );
     941         [ +  - ]:     332948 :     if (!scratch) {
     942                 :            :         return;
     943                 :            :     }
     944         [ +  - ]:     355356 :     rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN );
     945                 :            : }
     946                 :            : 
     947                 :            : static void
     948                 :    6968549 : internRelease (rtl_uString *pThis)
     949                 :            : {
     950                 :            :     oslMutex pPoolMutex;
     951                 :            : 
     952                 :    6968549 :     rtl_uString *pFree = NULL;
     953         [ +  + ]:    6968549 :     if ( SAL_STRING_REFCOUNT(
     954                 :            :              osl_decrementInterlockedCount( &(pThis->refCount) ) ) == 0)
     955                 :            :     {
     956                 :     332695 :         pPoolMutex = getInternMutex();
     957                 :     332695 :         osl_acquireMutex( pPoolMutex );
     958                 :            : 
     959                 :     332695 :         rtl_str_hash_remove (pThis);
     960                 :            : 
     961                 :            :         /* May have been separately acquired */
     962         [ +  - ]:     332695 :         if ( SAL_STRING_REFCOUNT(
     963                 :            :                  osl_incrementInterlockedCount( &(pThis->refCount) ) ) == 1 )
     964                 :            :         {
     965                 :            :             /* we got the last ref */
     966                 :     332695 :             pFree = pThis;
     967                 :            :         }
     968                 :            :         else /* very unusual */
     969                 :            :         {
     970                 :          0 :             internRelease (pThis);
     971                 :            :         }
     972                 :            : 
     973                 :     332695 :         osl_releaseMutex( pPoolMutex );
     974                 :            :     }
     975         [ +  + ]:    6968549 :     if (pFree)
     976                 :     332695 :         rtl_freeMemory (pFree);
     977                 :    6968549 : }
     978                 :            : 
     979                 :   24047524 : sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints(
     980                 :            :     rtl_uString const * string, sal_Int32 * indexUtf16,
     981                 :            :     sal_Int32 incrementCodePoints)
     982                 :            : {
     983                 :            :     sal_Int32 n;
     984                 :            :     sal_Unicode cu;
     985                 :            :     sal_uInt32 cp;
     986                 :            :     OSL_ASSERT(string != NULL && indexUtf16 != NULL);
     987                 :   24047524 :     n = *indexUtf16;
     988                 :            :     OSL_ASSERT(n >= 0 && n <= string->length);
     989         [ +  + ]:   24418626 :     while (incrementCodePoints < 0) {
     990                 :            :         OSL_ASSERT(n > 0);
     991                 :     371102 :         cu = string->buffer[--n];
     992 [ +  + ][ -  + ]:     371102 :         if (SAL_RTL_IS_LOW_SURROGATE(cu) && n != 0 &&
         [ #  # ][ #  # ]
                 [ #  # ]
     993                 :          0 :             SAL_RTL_IS_HIGH_SURROGATE(string->buffer[n - 1]))
     994                 :            :         {
     995                 :          0 :             --n;
     996                 :            :         }
     997                 :     371102 :         ++incrementCodePoints;
     998                 :            :     }
     999                 :            :     OSL_ASSERT(n >= 0 && n < string->length);
    1000                 :   24047524 :     cu = string->buffer[n];
    1001 [ +  + ][ +  + ]:   24047524 :     if (SAL_RTL_IS_HIGH_SURROGATE(cu) && string->length - n >= 2 &&
         [ +  - ][ +  - ]
                 [ +  - ]
    1002                 :         20 :         SAL_RTL_IS_LOW_SURROGATE(string->buffer[n + 1]))
    1003                 :            :     {
    1004                 :         10 :         cp = SAL_RTL_COMBINE_SURROGATES(cu, string->buffer[n + 1]);
    1005                 :            :     } else {
    1006                 :   24047514 :         cp = cu;
    1007                 :            :     }
    1008         [ +  + ]:   35417119 :     while (incrementCodePoints > 0) {
    1009                 :            :         OSL_ASSERT(n < string->length);
    1010                 :   11369595 :         cu = string->buffer[n++];
    1011 [ +  + ][ +  + ]:   11369595 :         if (SAL_RTL_IS_HIGH_SURROGATE(cu) && n != string->length &&
         [ +  - ][ +  - ]
                 [ +  - ]
    1012                 :         20 :             SAL_RTL_IS_LOW_SURROGATE(string->buffer[n]))
    1013                 :            :         {
    1014                 :         10 :             ++n;
    1015                 :            :         }
    1016                 :   11369595 :         --incrementCodePoints;
    1017                 :            :     }
    1018                 :            :     OSL_ASSERT(n >= 0 && n <= string->length);
    1019                 :   24047524 :     *indexUtf16 = n;
    1020                 :   24047524 :     return cp;
    1021                 :            : }
    1022                 :            : 
    1023                 :   18881940 : sal_Bool rtl_convertStringToUString(
    1024                 :            :     rtl_uString ** target, char const * source, sal_Int32 length,
    1025                 :            :     rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C()
    1026                 :            : {
    1027                 :            :     sal_uInt32 info;
    1028         [ +  - ]:   18881940 :     rtl_string2UString_status(target, source, length, encoding, flags, &info);
    1029                 :   18881940 :     return (sal_Bool) ((info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0);
    1030                 :            : }
    1031                 :            : 
    1032                 :     216421 : void rtl_uString_newReplaceFirst(
    1033                 :            :     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
    1034                 :            :     rtl_uString const * to, sal_Int32 * index) SAL_THROW_EXTERN_C()
    1035                 :            : {
    1036                 :            :     assert(str != 0);
    1037                 :            :     assert(index != 0);
    1038                 :            :     assert(*index >= 0 && *index <= str->length);
    1039                 :            :     assert(from != 0);
    1040                 :            :     assert(to != 0);
    1041                 :            :     sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
    1042                 :     216421 :         str->buffer + *index, str->length - *index, from->buffer, from->length);
    1043         [ +  + ]:     216421 :     if (i == -1) {
    1044                 :     194862 :         rtl_uString_assign(newStr, str);
    1045                 :            :     } else {
    1046                 :            :         assert(i <= str->length - *index);
    1047                 :      21559 :         i += *index;
    1048                 :            :         assert(from->length <= str->length);
    1049         [ -  + ]:      21559 :         if (str->length - from->length > SAL_MAX_INT32 - to->length) {
    1050                 :          0 :             std::abort();
    1051                 :            :         }
    1052                 :      21559 :         sal_Int32 n = str->length - from->length + to->length;
    1053                 :      21559 :         rtl_uString_acquire(str); // in case *newStr == str
    1054                 :      21559 :         rtl_uString_new_WithLength(newStr, n);
    1055         [ +  + ]:      21559 :         if (n != 0) {
    1056                 :       2686 :             (*newStr)->length = n;
    1057                 :            :             assert(i >= 0 && i < str->length);
    1058                 :            :             memcpy(
    1059                 :       2686 :                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
    1060                 :            :             memcpy(
    1061                 :       2686 :                 (*newStr)->buffer + i, to->buffer,
    1062                 :       5372 :                 to->length * sizeof (sal_Unicode));
    1063                 :            :             memcpy(
    1064                 :       2686 :                 (*newStr)->buffer + i + to->length,
    1065                 :       2686 :                 str->buffer + i + from->length,
    1066                 :       2686 :                 (str->length - i - from->length) * sizeof (sal_Unicode));
    1067                 :            :         }
    1068                 :      21559 :         rtl_uString_release(str);
    1069                 :            :     }
    1070                 :     216421 :     *index = i;
    1071                 :     216421 : }
    1072                 :            : 
    1073                 :      41907 : void rtl_uString_newReplaceFirstAsciiL(
    1074                 :            :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1075                 :            :     sal_Int32 fromLength, rtl_uString const * to, sal_Int32 * index)
    1076                 :            :     SAL_THROW_EXTERN_C()
    1077                 :            : {
    1078                 :            :     assert(str != 0);
    1079                 :            :     assert(index != 0);
    1080                 :            :     assert(*index >= 0 && *index <= str->length);
    1081                 :            :     assert(fromLength >= 0);
    1082                 :            :     assert(to != 0);
    1083                 :            :     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
    1084                 :      41907 :         str->buffer + *index, str->length - *index, from, fromLength);
    1085         [ +  + ]:      41907 :     if (i == -1) {
    1086                 :      24701 :         rtl_uString_assign(newStr, str);
    1087                 :            :     } else {
    1088                 :            :         assert(i <= str->length - *index);
    1089                 :      17206 :         i += *index;
    1090                 :            :         assert(fromLength <= str->length);
    1091         [ -  + ]:      17206 :         if (str->length - fromLength > SAL_MAX_INT32 - to->length) {
    1092                 :          0 :             std::abort();
    1093                 :            :         }
    1094                 :      17206 :         sal_Int32 n = str->length - fromLength + to->length;
    1095                 :      17206 :         rtl_uString_acquire(str); // in case *newStr == str
    1096         [ +  - ]:      17206 :         if (n != 0) {
    1097                 :      17206 :             rtl_uString_new_WithLength(newStr, n);
    1098                 :      17206 :             (*newStr)->length = n;
    1099                 :            :             assert(i >= 0 && i < str->length);
    1100                 :            :             memcpy(
    1101                 :      17206 :                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
    1102                 :            :             memcpy(
    1103                 :      17206 :                 (*newStr)->buffer + i, to->buffer,
    1104                 :      34412 :                 to->length * sizeof (sal_Unicode));
    1105                 :            :             memcpy(
    1106                 :      17206 :                 (*newStr)->buffer + i + to->length,
    1107                 :      17206 :                 str->buffer + i + fromLength,
    1108                 :      17206 :                 (str->length - i - fromLength) * sizeof (sal_Unicode));
    1109                 :            :         }
    1110                 :      17206 :         rtl_uString_release(str);
    1111                 :            :     }
    1112                 :      41907 :     *index = i;
    1113                 :      41907 : }
    1114                 :            : 
    1115                 :      14257 : void rtl_uString_newReplaceFirstAsciiLAsciiL(
    1116                 :            :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1117                 :            :     sal_Int32 fromLength, char const * to, sal_Int32 toLength,
    1118                 :            :     sal_Int32 * index) SAL_THROW_EXTERN_C()
    1119                 :            : {
    1120                 :            :     assert(str != 0);
    1121                 :            :     assert(index != 0);
    1122                 :            :     assert(*index >= 0 && *index <= str->length);
    1123                 :            :     assert(fromLength >= 0);
    1124                 :            :     assert(to != 0);
    1125                 :            :     assert(toLength >= 0);
    1126                 :            :     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
    1127                 :      14257 :         str->buffer + *index, str->length - *index, from, fromLength);
    1128         [ +  + ]:      14257 :     if (i == -1) {
    1129                 :      11975 :         rtl_uString_assign(newStr, str);
    1130                 :            :     } else {
    1131                 :            :         assert(i <= str->length - *index);
    1132                 :       2282 :         i += *index;
    1133                 :            :         assert(fromLength <= str->length);
    1134         [ -  + ]:       2282 :         if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
    1135                 :          0 :             std::abort();
    1136                 :            :         }
    1137                 :       2282 :         sal_Int32 n = str->length - fromLength + toLength;
    1138                 :       2282 :         rtl_uString_acquire(str); // in case *newStr == str
    1139         [ +  - ]:       2282 :         if (n != 0) {
    1140                 :       2282 :             rtl_uString_new_WithLength(newStr, n);
    1141                 :       2282 :             (*newStr)->length = n;
    1142                 :            :             assert(i >= 0 && i < str->length);
    1143                 :            :             memcpy(
    1144                 :       2282 :                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
    1145         [ +  + ]:       2861 :             for (sal_Int32 j = 0; j != toLength; ++j) {
    1146                 :            :                 assert(static_cast< unsigned char >(to[j]) <= 0x7F);
    1147                 :        579 :                 (*newStr)->buffer[i + j] = to[j];
    1148                 :            :             }
    1149                 :            :             memcpy(
    1150                 :       2282 :                 (*newStr)->buffer + i + toLength,
    1151                 :       2282 :                 str->buffer + i + fromLength,
    1152                 :       2282 :                 (str->length - i - fromLength) * sizeof (sal_Unicode));
    1153                 :            :         }
    1154                 :       2282 :         rtl_uString_release(str);
    1155                 :            :     }
    1156                 :      14257 :     *index = i;
    1157                 :      14257 : }
    1158                 :            : 
    1159                 :     194852 : void rtl_uString_newReplaceAll(
    1160                 :            :     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
    1161                 :            :     rtl_uString const * to) SAL_THROW_EXTERN_C()
    1162                 :            : {
    1163                 :            :     assert(to != 0);
    1164                 :     194852 :     rtl_uString_assign(newStr, str);
    1165                 :     216396 :     for (sal_Int32 i = 0;; i += to->length) {
    1166                 :     216396 :         rtl_uString_newReplaceFirst(newStr, *newStr, from, to, &i);
    1167         [ +  + ]:     216396 :         if (i == -1) {
    1168                 :     194852 :             break;
    1169                 :            :         }
    1170                 :            :     }
    1171                 :     194852 : }
    1172                 :            : 
    1173                 :      24691 : void rtl_uString_newReplaceAllAsciiL(
    1174                 :            :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1175                 :            :     sal_Int32 fromLength, rtl_uString const * to) SAL_THROW_EXTERN_C()
    1176                 :            : {
    1177                 :            :     assert(to != 0);
    1178                 :      24691 :     rtl_uString_assign(newStr, str);
    1179                 :      41877 :     for (sal_Int32 i = 0;; i += to->length) {
    1180                 :            :         rtl_uString_newReplaceFirstAsciiL(
    1181                 :      41877 :             newStr, *newStr, from, fromLength, to, &i);
    1182         [ +  + ]:      41877 :         if (i == -1) {
    1183                 :      24691 :             break;
    1184                 :            :         }
    1185                 :            :     }
    1186                 :      24691 : }
    1187                 :            : 
    1188                 :      11965 : void rtl_uString_newReplaceAllAsciiLAsciiL(
    1189                 :            :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1190                 :            :     sal_Int32 fromLength, char const * to, sal_Int32 toLength)
    1191                 :            :     SAL_THROW_EXTERN_C()
    1192                 :            : {
    1193                 :            :     assert(toLength >= 0);
    1194                 :      11965 :     rtl_uString_assign(newStr, str);
    1195                 :      14227 :     for (sal_Int32 i = 0;; i += toLength) {
    1196                 :            :         rtl_uString_newReplaceFirstAsciiLAsciiL(
    1197                 :      14227 :             newStr, *newStr, from, fromLength, to, toLength, &i);
    1198         [ +  + ]:      14227 :         if (i == -1) {
    1199                 :      11965 :             break;
    1200                 :            :         }
    1201                 :            :     }
    1202                 :      11965 : }
    1203                 :            : 
    1204                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10