LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sal/rtl - ustring.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 406 476 85.3 %
Date: 2013-07-09 Functions: 33 35 94.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10