LCOV - code coverage report
Current view: top level - sal/rtl - ustring.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 430 486 88.5 %
Date: 2015-06-13 12:38:46 Functions: 34 36 94.4 %
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 <rtl/character.hxx>
      43             : #include <rtl/ustring.h>
      44             : 
      45             : #include "rtl/math.h"
      46             : 
      47             : /* ======================================================================= */
      48             : 
      49             : /* static data to be referenced by all empty strings
      50             :  * the refCount is predefined to 1 and must never become 0 !
      51             :  */
      52             : static rtl_uString const aImplEmpty_rtl_uString =
      53             : {
      54             :     (sal_Int32) (SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32    refCount; */
      55             :     0,                                               /*sal_Int32    length;   */
      56             :     { 0 }                                            /*sal_Unicode  buffer[1];*/
      57             : };
      58             : 
      59             : /* ======================================================================= */
      60             : /* These macros are for the "poor-man templates" included from
      61             :  * the strtmpl.cxx just below, used to share code between here and
      62             :  * string.cxx
      63             :  */
      64             : 
      65             : #define IMPL_RTL_IS_USTRING         1
      66             : 
      67             : #define IMPL_RTL_STRCODE            sal_Unicode
      68             : #define IMPL_RTL_USTRCODE( c )      (c)
      69             : #define IMPL_RTL_STRNAME( n )       rtl_ustr_ ## n
      70             : 
      71             : #define IMPL_RTL_STRINGNAME( n )    rtl_uString_ ## n
      72             : #define IMPL_RTL_STRINGDATA         rtl_uString
      73             : #define IMPL_RTL_EMPTYSTRING        aImplEmpty_rtl_uString
      74             : 
      75             : static void internRelease (rtl_uString *pThis);
      76             : 
      77             : #if USE_SDT_PROBES
      78             : #define RTL_LOG_STRING_BITS         16
      79             : #endif
      80             : 
      81             : /* ======================================================================= */
      82             : 
      83             : /* Include String/UString template code */
      84             : 
      85             : #include "strtmpl.cxx"
      86             : 
      87             : #undef IMPL_RTL_EMPTYSTRING
      88             : #undef IMPL_RTL_IS_USTRING
      89             : #undef IMPL_RTL_STRCODE
      90             : #undef IMPL_RTL_STRINGDATA
      91             : #undef IMPL_RTL_STRINGNAME
      92             : #undef IMPL_RTL_STRNAME
      93             : #undef IMPL_RTL_USTRCODE
      94             : #undef RTL_LOG_STRING_BITS
      95             : 
      96     4306897 : sal_Int32 rtl_ustr_indexOfAscii_WithLength(
      97             :     sal_Unicode const * str, sal_Int32 len,
      98             :     char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
      99             : {
     100             :     assert(len >= 0);
     101             :     assert(subLen >= 0);
     102     4306897 :     if (subLen > 0 && subLen <= len) {
     103             :         sal_Int32 i;
     104    43944056 :         for (i = 0; i <= len - subLen; ++i) {
     105    41217058 :             if (rtl_ustr_asciil_reverseEquals_WithLength(
     106    41217058 :                     str + i, subStr, subLen))
     107             :             {
     108      209426 :                 return i;
     109             :             }
     110             :         }
     111             :     }
     112     4097471 :     return -1;
     113             : }
     114             : 
     115        3384 : sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength(
     116             :     sal_Unicode const * str, sal_Int32 len,
     117             :     char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
     118             : {
     119             :     assert(len >= 0);
     120             :     assert(subLen >= 0);
     121        3384 :     if (subLen > 0 && subLen <= len) {
     122             :         sal_Int32 i;
     123        3779 :         for (i = len - subLen; i >= 0; --i) {
     124        3778 :             if (rtl_ustr_asciil_reverseEquals_WithLength(
     125        3778 :                     str + i, subStr, subLen))
     126             :             {
     127        3382 :                 return i;
     128             :             }
     129             :         }
     130             :     }
     131           2 :     return -1;
     132             : }
     133             : 
     134          61 : sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f)
     135             :     SAL_THROW_EXTERN_C()
     136             : {
     137             :     assert(pStr);
     138          61 :     rtl_uString * pResult = NULL;
     139             :     sal_Int32 nLen;
     140             :     rtl_math_doubleToUString(
     141             :         &pResult, 0, 0, f, rtl_math_StringFormat_G,
     142             :         RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
     143          61 :         0, sal_True);
     144          61 :     nLen = pResult->length;
     145             :     OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT);
     146          61 :     memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
     147          61 :     rtl_uString_release(pResult);
     148          61 :     return nLen;
     149             : }
     150             : 
     151      101926 : sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d)
     152             :     SAL_THROW_EXTERN_C()
     153             : {
     154             :     assert(pStr);
     155      101926 :     rtl_uString * pResult = NULL;
     156             :     sal_Int32 nLen;
     157             :     rtl_math_doubleToUString(
     158             :         &pResult, 0, 0, d, rtl_math_StringFormat_G,
     159             :         RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
     160      101926 :         0, sal_True);
     161      101926 :     nLen = pResult->length;
     162             :     OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE);
     163      101926 :     memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
     164      101926 :     rtl_uString_release(pResult);
     165      101926 :     return nLen;
     166             : }
     167             : 
     168             : namespace {
     169             : 
     170             : // Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
     171             : // outside the range of representable values of type 'float'":
     172         116 : float doubleToFloat(double x) {
     173             :     return
     174         116 :         x < -std::numeric_limits<float>::max()
     175           2 :         ? -std::numeric_limits<float>::infinity()
     176         114 :         : x > std::numeric_limits<float>::max()
     177             :         ? std::numeric_limits<float>::infinity()
     178         232 :         : static_cast<float>(x);
     179             : }
     180             : 
     181             : }
     182             : 
     183         116 : float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
     184             : {
     185             :     assert(pStr);
     186             :     return doubleToFloat(rtl_math_uStringToDouble(pStr,
     187         116 :                                             pStr + rtl_ustr_getLength(pStr),
     188         116 :                                             '.', 0, 0, 0));
     189             : }
     190             : 
     191       31534 : double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
     192             : {
     193             :     assert(pStr);
     194       31534 :     return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.',
     195       31534 :                                     0, 0, 0);
     196             : }
     197             : 
     198             : /* ======================================================================= */
     199             : 
     200       41724 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1,
     201             :                                            const sal_Char* pStr2 )
     202             :     SAL_THROW_EXTERN_C()
     203             : {
     204             :     assert(pStr1);
     205             :     assert(pStr2);
     206             :     sal_Int32 nRet;
     207      339596 :     while ( ((nRet = ((sal_Int32)(*pStr1))-
     208      148936 :                      ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
     209             :             *pStr2 )
     210             :     {
     211             :         /* Check ASCII range */
     212             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     213             :                     "rtl_ustr_ascii_compare - Found char > 127" );
     214      107212 :         pStr1++;
     215      107212 :         pStr2++;
     216             :     }
     217             : 
     218       41724 :     return nRet;
     219             : }
     220             : 
     221             : /* ----------------------------------------------------------------------- */
     222             : 
     223  1514202229 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1,
     224             :                                                       sal_Int32 nStr1Len,
     225             :                                                       const sal_Char* pStr2 )
     226             :     SAL_THROW_EXTERN_C()
     227             : {
     228             :     assert(pStr1);
     229             :     assert(nStr1Len >= 0);
     230             :     assert(pStr2);
     231  1514202229 :     sal_Int32 nRet = 0;
     232  9284219563 :     while( ((nRet = (nStr1Len ? (sal_Int32)(*pStr1) : 0)-
     233  2407568694 :                     ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
     234  6255814709 :            nStr1Len && *pStr2 )
     235             :     {
     236             :         /* Check ASCII range */
     237             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     238             :                     "rtl_ustr_ascii_compare_WithLength - Found char > 127" );
     239  2370806438 :         pStr1++;
     240  2370806438 :         pStr2++;
     241  2370806438 :         nStr1Len--;
     242             :     }
     243             : 
     244  1514202229 :     return nRet;
     245             : }
     246             : 
     247             : /* ----------------------------------------------------------------------- */
     248             : 
     249   147952605 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1,
     250             :                                                                sal_Int32 nStr1Len,
     251             :                                                                const sal_Char* pStr2,
     252             :                                                                sal_Int32 nShortenedLength )
     253             :     SAL_THROW_EXTERN_C()
     254             : {
     255             :     assert(nStr1Len >= 0);
     256             :     assert(nShortenedLength >= 0);
     257   147952605 :     const sal_Unicode*  pStr1End = pStr1 + nStr1Len;
     258             :     sal_Int32           nRet;
     259   312034757 :     while ( (nShortenedLength > 0) &&
     260   161857091 :             (pStr1 < pStr1End) && *pStr2 )
     261             :     {
     262             :         /* Check ASCII range */
     263             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     264             :                     "rtl_ustr_ascii_shortenedCompare_WithLength - Found char > 127" );
     265             : 
     266   161857091 :         nRet = ((sal_Int32)*pStr1)-
     267   161857091 :                ((sal_Int32)(unsigned char)*pStr2);
     268   161857091 :         if ( nRet != 0 )
     269   145727544 :             return nRet;
     270             : 
     271    16129547 :         nShortenedLength--;
     272    16129547 :         pStr1++;
     273    16129547 :         pStr2++;
     274             :     }
     275             : 
     276     2225061 :     if ( nShortenedLength <= 0 )
     277     2208838 :         return 0;
     278             : 
     279       16223 :     if ( *pStr2 )
     280             :     {
     281             :         OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
     282             :         // first is a substring of the second string => less (negative value)
     283       16223 :         nRet = -1;
     284             :     }
     285             :     else
     286             :     {
     287             :         // greater or equal
     288           0 :         nRet = pStr1End - pStr1;
     289             :     }
     290             : 
     291       16223 :     return nRet;
     292             : }
     293             : 
     294             : /* ----------------------------------------------------------------------- */
     295             : 
     296        7628 : sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1,
     297             :                                                               sal_Int32 nStr1Len,
     298             :                                                               const sal_Char* pStr2,
     299             :                                                               sal_Int32 nStr2Len )
     300             :     SAL_THROW_EXTERN_C()
     301             : {
     302             :     assert(nStr1Len >= 0 && nStr2Len >= 0);
     303        7628 :     const sal_Unicode*  pStr1Run = pStr1+nStr1Len;
     304        7628 :     const sal_Char*     pStr2Run = pStr2+nStr2Len;
     305             :     sal_Int32           nRet;
     306       17918 :     while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
     307             :     {
     308             :         /* Check ASCII range */
     309             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     310             :                     "rtl_ustr_asciil_reverseCompare_WithLength - Found char > 127" );
     311       10187 :         pStr1Run--;
     312       10187 :         pStr2Run--;
     313       10187 :         nRet = ((sal_Int32)*pStr1Run)-((sal_Int32)*pStr2Run);
     314       10187 :         if ( nRet )
     315        7525 :             return nRet;
     316             :     }
     317             : 
     318         103 :     return nStr1Len - nStr2Len;
     319             : }
     320             : 
     321             : /* ----------------------------------------------------------------------- */
     322             : 
     323   747792761 : sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1,
     324             :                                                               const sal_Char* pStr2,
     325             :                                                               sal_Int32 nStrLen )
     326             :     SAL_THROW_EXTERN_C()
     327             : {
     328             :     assert(nStrLen >= 0);
     329   747792761 :     const sal_Unicode*  pStr1Run = pStr1+nStrLen;
     330   747792761 :     const sal_Char*     pStr2Run = pStr2+nStrLen;
     331  6415420040 :     while ( pStr1 < pStr1Run )
     332             :     {
     333             :         /* Check ASCII range */
     334             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     335             :                     "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
     336  5379838081 :         pStr1Run--;
     337  5379838081 :         pStr2Run--;
     338  5379838081 :         if( *pStr1Run != (sal_Unicode)*pStr2Run )
     339   460003563 :             return sal_False;
     340             :     }
     341             : 
     342   287789198 :     return sal_True;
     343             : }
     344             : 
     345             : /* ----------------------------------------------------------------------- */
     346             : 
     347           0 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1,
     348             :                                                           const sal_Char* pStr2 )
     349             :     SAL_THROW_EXTERN_C()
     350             : {
     351             :     assert(pStr1);
     352             :     assert(pStr2);
     353             :     sal_Int32   nRet;
     354             :     sal_Int32   c1;
     355             :     sal_Int32   c2;
     356           0 :     do
     357             :     {
     358             :         /* Check ASCII range */
     359             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     360             :                     "rtl_ustr_ascii_compareIgnoreAsciiCase - Found char > 127" );
     361             :         /* If character between 'A' and 'Z', than convert it to lowercase */
     362           0 :         c1 = (sal_Int32)*pStr1;
     363           0 :         c2 = (sal_Int32)((unsigned char)*pStr2);
     364           0 :         if ( (c1 >= 65) && (c1 <= 90) )
     365           0 :             c1 += 32;
     366           0 :         if ( (c2 >= 65) && (c2 <= 90) )
     367           0 :             c2 += 32;
     368           0 :         nRet = c1-c2;
     369           0 :         if ( nRet != 0 )
     370           0 :             return nRet;
     371             : 
     372           0 :         pStr1++;
     373           0 :         pStr2++;
     374             :     }
     375             :     while ( c2 );
     376             : 
     377           0 :     return 0;
     378             : }
     379             : 
     380             : /* ----------------------------------------------------------------------- */
     381             : 
     382   570833634 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
     383             :                                                                      sal_Int32 nStr1Len,
     384             :                                                                      const sal_Char* pStr2 )
     385             :     SAL_THROW_EXTERN_C()
     386             : {
     387             :     assert(nStr1Len >= 0);
     388             :     assert(pStr2);
     389             :     sal_Int32   nRet;
     390             :     sal_Int32   c1;
     391             :     sal_Int32   c2;
     392   259199641 :     do
     393             :     {
     394             :         /* Check ASCII range */
     395             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     396             :                     "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength - Found char > 127" );
     397   570833634 :         if ( !nStr1Len )
     398    28063427 :             return *pStr2 == '\0' ? 0 : -1;
     399             : 
     400             :         /* If character between 'A' and 'Z', than convert it to lowercase */
     401   542770207 :         c1 = (sal_Int32)*pStr1;
     402   542770207 :         c2 = (sal_Int32)((unsigned char)*pStr2);
     403   542770207 :         if ( (c1 >= 65) && (c1 <= 90) )
     404   287782164 :             c1 += 32;
     405   542770207 :         if ( (c2 >= 65) && (c2 <= 90) )
     406   284750716 :             c2 += 32;
     407   542770207 :         nRet = c1-c2;
     408   542770207 :         if ( nRet != 0 )
     409   283570566 :             return nRet;
     410             : 
     411   259199641 :         pStr1++;
     412   259199641 :         pStr2++;
     413   259199641 :         nStr1Len--;
     414             :     }
     415             :     while( c2 );
     416             : 
     417           0 :     return 0;
     418             : }
     419             : 
     420      478077 : sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
     421             :     sal_Unicode const * first, sal_Int32 firstLen,
     422             :     char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C()
     423             : {
     424             :     assert(firstLen >= 0 && secondLen >= 0);
     425             :     sal_Int32 i;
     426      478077 :     sal_Int32 len = firstLen < secondLen ? firstLen : secondLen;
     427     1107031 :     for (i = 0; i < len; ++i) {
     428             :         /* Check ASCII range */
     429             :         SAL_WARN_IF( ((unsigned char)*second) > 127, "rtl.string",
     430             :                     "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths - Found char > 127" );
     431     1040380 :         sal_Int32 c1 = *first++;
     432     1040380 :         sal_Int32 c2 = (unsigned char) *second++;
     433             :         sal_Int32 d;
     434     1040380 :         if (c1 >= 65 && c1 <= 90) {
     435      116985 :             c1 += 32;
     436             :         }
     437     1040380 :         if (c2 >= 65 && c2 <= 90) {
     438       98301 :             c2 += 32;
     439             :         }
     440     1040380 :         d = c1 - c2;
     441     1040380 :         if (d != 0) {
     442      411426 :             return d;
     443             :         }
     444             :     }
     445       66651 :     return firstLen - secondLen;
     446             : }
     447             : 
     448             : /* ----------------------------------------------------------------------- */
     449             : 
     450     4097596 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
     451             :                                                                               sal_Int32 nStr1Len,
     452             :                                                                               const sal_Char* pStr2,
     453             :                                                                               sal_Int32 nShortenedLength )
     454             :     SAL_THROW_EXTERN_C()
     455             : {
     456             :     assert(nStr1Len >= 0);
     457             :     assert(nShortenedLength >= 0);
     458     4097596 :     const sal_Unicode*  pStr1End = pStr1 + nStr1Len;
     459             :     sal_Int32           nRet;
     460             :     sal_Int32           c1;
     461             :     sal_Int32           c2;
     462    10139322 :     while ( (nShortenedLength > 0) &&
     463     5832790 :             (pStr1 < pStr1End) && *pStr2 )
     464             :     {
     465             :         /* Check ASCII range */
     466             :         SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
     467             :                     "rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength - Found char > 127" );
     468             : 
     469             :         /* If character between 'A' and 'Z', than convert it to lowercase */
     470     5832790 :         c1 = (sal_Int32)*pStr1;
     471     5832790 :         c2 = (sal_Int32)((unsigned char)*pStr2);
     472     5832790 :         if ( (c1 >= 65) && (c1 <= 90) )
     473      311834 :             c1 += 32;
     474     5832790 :         if ( (c2 >= 65) && (c2 <= 90) )
     475      311827 :             c2 += 32;
     476     5832790 :         nRet = c1-c2;
     477     5832790 :         if ( nRet != 0 )
     478     3888660 :             return nRet;
     479             : 
     480     1944130 :         nShortenedLength--;
     481     1944130 :         pStr1++;
     482     1944130 :         pStr2++;
     483             :     }
     484             : 
     485      208936 :     if ( nShortenedLength <= 0 )
     486      208869 :         return 0;
     487             : 
     488          67 :     if ( *pStr2 )
     489             :     {
     490             :         OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
     491             :         // first is a substring of the second string => less (negative value)
     492          67 :         nRet = -1;
     493             :     }
     494             :     else
     495             :     {
     496             :         // greater or equal
     497           0 :         nRet = pStr1End - pStr1;
     498             :     }
     499             : 
     500          67 :     return nRet;
     501             : }
     502             : 
     503             : /* ----------------------------------------------------------------------- */
     504             : 
     505    14511431 : void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis,
     506             :                                         const sal_Char* pCharStr )
     507             :     SAL_THROW_EXTERN_C()
     508             : {
     509             :     assert(ppThis);
     510             :     sal_Int32 nLen;
     511             : 
     512    14511431 :     if ( pCharStr )
     513             :     {
     514    14511263 :         const sal_Char* pTempStr = pCharStr;
     515   174852654 :         while( *pTempStr )
     516   145830128 :             pTempStr++;
     517    14511263 :         nLen = pTempStr-pCharStr;
     518             :     }
     519             :     else
     520         168 :         nLen = 0;
     521             : 
     522    14511431 :     if ( !nLen )
     523             :     {
     524      148799 :         rtl_uString_new( ppThis );
     525    14660230 :         return;
     526             :     }
     527             : 
     528    14362632 :     if ( *ppThis )
     529        7438 :         rtl_uString_release( *ppThis );
     530             : 
     531    14362632 :     *ppThis = rtl_uString_ImplAlloc( nLen );
     532             :     OSL_ASSERT(*ppThis != NULL);
     533    14362632 :     if ( (*ppThis) )
     534             :     {
     535    14362632 :         sal_Unicode* pBuffer = (*ppThis)->buffer;
     536   145830164 :         do
     537             :         {
     538             :             assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
     539   145830164 :             *pBuffer = *pCharStr;
     540   145830164 :             pBuffer++;
     541   145830164 :             pCharStr++;
     542             :         }
     543             :         while ( *pCharStr );
     544             : 
     545             :         RTL_LOG_STRING_NEW( *ppThis );
     546             :     }
     547             : }
     548             : 
     549       18310 : void SAL_CALL rtl_uString_newFromCodePoints(
     550             :     rtl_uString ** newString, sal_uInt32 const * codePoints,
     551             :     sal_Int32 codePointCount) SAL_THROW_EXTERN_C()
     552             : {
     553             :     sal_Int32 n;
     554             :     sal_Int32 i;
     555             :     sal_Unicode * p;
     556             :     assert(newString != nullptr);
     557             :     assert((codePoints != nullptr || codePointCount == 0) && codePointCount >= 0);
     558       18310 :     if (codePointCount == 0) {
     559        4036 :         rtl_uString_new(newString);
     560        4036 :         return;
     561             :     }
     562       14274 :     if (*newString != NULL) {
     563           0 :         rtl_uString_release(*newString);
     564             :     }
     565       14274 :     n = codePointCount;
     566       28784 :     for (i = 0; i < codePointCount; ++i) {
     567             :         OSL_ASSERT(codePoints[i] <= 0x10FFFF);
     568       14510 :         if (codePoints[i] >= 0x10000) {
     569           4 :             ++n;
     570             :         }
     571             :     }
     572             :     /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
     573             :        representation with wrap around (the necessary number of UTF-16 code
     574             :        units will be no larger than 2 * SAL_MAX_INT32, represented as
     575             :        sal_Int32 -2): */
     576       14274 :     if (n < 0) {
     577             :         // coverity[dead_error_begin] - assumes wrap around
     578           0 :         *newString = NULL;
     579           0 :         return;
     580             :     }
     581       14274 :     *newString = rtl_uString_ImplAlloc(n);
     582       14274 :     if (*newString == NULL) {
     583           0 :         return;
     584             :     }
     585       14274 :     p = (*newString)->buffer;
     586       28784 :     for (i = 0; i < codePointCount; ++i) {
     587       14510 :         sal_uInt32 c = codePoints[i];
     588       14510 :         if (c < 0x10000) {
     589       14506 :             *p++ = (sal_Unicode) c;
     590             :         } else {
     591           4 :             *p++ = rtl::getHighSurrogate(c);
     592           4 :             *p++ = rtl::getLowSurrogate(c);
     593             :         }
     594             :     }
     595             :     RTL_LOG_STRING_NEW( *newString );
     596             : }
     597             : 
     598             : /* ======================================================================= */
     599             : 
     600    27415622 : static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen, bool * ascii )
     601             : {
     602             :     int             n;
     603             :     const sal_Char* pEndStr;
     604             : 
     605    27415622 :     *ascii = true;
     606    27415622 :     n = 0;
     607    27415622 :     pEndStr  = pStr+nLen;
     608   462839311 :     while ( pStr < pEndStr )
     609             :     {
     610   408008067 :         unsigned char c = (unsigned char)*pStr;
     611             : 
     612   408008067 :         if ( !(c & 0x80) )
     613   405381272 :             pStr++;
     614             :         else
     615             :         {
     616     2626795 :             if ( (c & 0xE0) == 0xC0 )
     617       38119 :                 pStr += 2;
     618     2588676 :             else if ( (c & 0xF0) == 0xE0 )
     619     2588669 :                 pStr += 3;
     620           7 :             else if ( (c & 0xF8) == 0xF0 )
     621           5 :                 pStr += 4;
     622           2 :             else if ( (c & 0xFC) == 0xF8 )
     623           0 :                 pStr += 5;
     624           2 :             else if ( (c & 0xFE) == 0xFC )
     625           0 :                 pStr += 6;
     626             :             else
     627           2 :                 pStr++;
     628     2626795 :             *ascii = false;
     629             :         }
     630             : 
     631   408008067 :         n++;
     632             :     }
     633             : 
     634    27415622 :     return n;
     635             : }
     636             : 
     637             : /* ----------------------------------------------------------------------- */
     638             : 
     639    42061305 : static void rtl_string2UString_status( rtl_uString** ppThis,
     640             :                                        const sal_Char* pStr,
     641             :                                        sal_Int32 nLen,
     642             :                                        rtl_TextEncoding eTextEncoding,
     643             :                                        sal_uInt32 nCvtFlags,
     644             :                                        sal_uInt32 *pInfo )
     645             : {
     646             :     OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding),
     647             :                "rtl_string2UString_status() - Wrong TextEncoding" );
     648             : 
     649    42061305 :     if ( !nLen )
     650             :     {
     651      730783 :         rtl_uString_new( ppThis );
     652      730783 :         if (pInfo != NULL) {
     653      558442 :             *pInfo = 0;
     654             :         }
     655             :     }
     656             :     else
     657             :     {
     658    41330522 :         if ( *ppThis )
     659    10613078 :             rtl_uString_release( *ppThis );
     660             : 
     661             :         /* Optimization for US-ASCII */
     662    41330522 :         if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
     663             :         {
     664             :             sal_Unicode* pBuffer;
     665    13745136 :             *ppThis = rtl_uString_ImplAlloc( nLen );
     666    13745136 :             if (*ppThis == NULL) {
     667           0 :                 if (pInfo != NULL) {
     668             :                     *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     669           0 :                         RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     670             :                 }
     671           0 :                 return;
     672             :             }
     673    13745136 :             pBuffer = (*ppThis)->buffer;
     674    13745136 :             sal_Int32 nLenCopy(nLen);
     675    13745136 :             const sal_Char *pStrCopy(pStr);
     676   197709810 :             do
     677             :             {
     678             :                 /* Check ASCII range */
     679   197709824 :                 if (static_cast<unsigned char>(*pStrCopy) > 127)
     680             :                 {
     681          14 :                     rtl_uString_release(*ppThis);
     682          14 :                     goto retry; // cancel loop - try again with the converter
     683             :                 }
     684             : 
     685   197709810 :                 *pBuffer = *pStrCopy;
     686   197709810 :                 pBuffer++;
     687   197709810 :                 pStrCopy++;
     688   197709810 :                 nLenCopy--;
     689             :             }
     690             :             while (nLenCopy);
     691    13745122 :             if (pInfo != NULL) {
     692    10149783 :                 *pInfo = 0;
     693             :             }
     694             :             RTL_LOG_STRING_NEW( *ppThis );
     695    13745122 :             return;
     696             :         }
     697             : retry:
     698             :         {
     699             :             rtl_uString*                pTemp;
     700    27585400 :             rtl_uString*                pTemp2 = NULL;
     701             :             rtl_TextToUnicodeConverter  hConverter;
     702             :             sal_uInt32                  nInfo;
     703             :             sal_Size                    nSrcBytes;
     704             :             sal_Size                    nDestChars;
     705             :             sal_Size                    nNewLen;
     706             : 
     707             :             /* Optimization for UTF-8 - we try to calculate the exact length */
     708             :             /* For all other encoding we try the maximum - and reallocate
     709             :                the buffer if needed */
     710    27585400 :             if ( eTextEncoding == RTL_TEXTENCODING_UTF8 )
     711             :             {
     712             :                 bool ascii;
     713    27415623 :                 nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen, &ascii );
     714             :                 /* Includes the string only ASCII, then we could copy
     715             :                    the buffer faster */
     716    27415623 :                 if ( ascii )
     717             :                 {
     718             :                     sal_Unicode* pBuffer;
     719    26703163 :                     *ppThis = rtl_uString_ImplAlloc( nLen );
     720    26703161 :                     if (*ppThis == NULL)
     721             :                     {
     722           0 :                         if (pInfo != NULL) {
     723             :                             *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     724           0 :                                 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     725             :                         }
     726    26703160 :                         return;
     727             :                     }
     728    26703162 :                     pBuffer = (*ppThis)->buffer;
     729   399148691 :                     do
     730             :                     {
     731             :                         assert(((unsigned char)*pStr) <= 127);
     732   399148691 :                         *pBuffer = *pStr;
     733   399148691 :                         pBuffer++;
     734   399148691 :                         pStr++;
     735   399148691 :                         nLen--;
     736             :                     }
     737             :                     while ( nLen );
     738    26703162 :                     if (pInfo != NULL) {
     739    13691281 :                         *pInfo = 0;
     740             :                     }
     741             :                     RTL_LOG_STRING_NEW( *ppThis );
     742    26703162 :                     return;
     743             :                 }
     744             :             }
     745             :             else
     746      169777 :                 nNewLen = nLen;
     747             : 
     748      882237 :             nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH;
     749      882237 :             hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
     750             : 
     751      882237 :             pTemp = rtl_uString_ImplAlloc( nNewLen );
     752      882237 :             if (pTemp == NULL) {
     753           0 :                 if (pInfo != NULL) {
     754             :                     *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     755           0 :                         RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     756             :                 }
     757           0 :                 return;
     758             :             }
     759             :             nDestChars = rtl_convertTextToUnicode( hConverter, 0,
     760             :                                                    pStr, nLen,
     761             :                                                    pTemp->buffer, nNewLen,
     762             :                                                    nCvtFlags,
     763      882237 :                                                    &nInfo, &nSrcBytes );
     764             : 
     765             :             /* Buffer not big enough, try again with enough space */
     766             :             /* Shouldn't be the case, but if we get textencoding which
     767             :                could results in more unicode characters we have this
     768             :                code here. Could be the case for apple encodings */
     769     1764531 :             while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL )
     770             :             {
     771          57 :                 rtl_freeMemory( pTemp );
     772          57 :                 nNewLen += 8;
     773          57 :                 pTemp = rtl_uString_ImplAlloc( nNewLen );
     774          57 :                 if (pTemp == NULL) {
     775           0 :                     if (pInfo != NULL) {
     776             :                         *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
     777           0 :                             RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     778             :                     }
     779           0 :                     return;
     780             :                 }
     781             :                 nDestChars = rtl_convertTextToUnicode( hConverter, 0,
     782             :                                                        pStr, nLen,
     783             :                                                        pTemp->buffer, nNewLen,
     784             :                                                        nCvtFlags,
     785          57 :                                                        &nInfo, &nSrcBytes );
     786             :             }
     787             : 
     788      882237 :             if (pInfo)
     789       36510 :                 *pInfo = nInfo;
     790             : 
     791             :             /* Set the buffer to the correct size or if there is too
     792             :                much overhead, reallocate to the correct size */
     793      882237 :             if ( nNewLen > nDestChars+8 )
     794             :             {
     795           4 :                 pTemp2 = rtl_uString_ImplAlloc( nDestChars );
     796             :             }
     797      882237 :             if (pTemp2 != NULL)
     798             :             {
     799           4 :                 rtl_str_ImplCopy(pTemp2->buffer, pTemp->buffer, nDestChars);
     800           4 :                 rtl_freeMemory(pTemp);
     801           4 :                 pTemp = pTemp2;
     802             :             }
     803             :             else
     804             :             {
     805      882233 :                 pTemp->length = nDestChars;
     806      882233 :                 pTemp->buffer[nDestChars] = 0;
     807             :             }
     808             : 
     809      882237 :             rtl_destroyTextToUnicodeConverter( hConverter );
     810      882237 :             *ppThis = pTemp;
     811             : 
     812             :             /* Results the conversion in an empty buffer -
     813             :                create an empty string */
     814      882237 :             if ( pTemp && !nDestChars )
     815           3 :                 rtl_uString_new( ppThis );
     816             :         }
     817             :     }
     818             :     RTL_LOG_STRING_NEW( *ppThis );
     819             : }
     820             : 
     821    16659250 : void SAL_CALL rtl_string2UString( rtl_uString** ppThis,
     822             :                                   const sal_Char* pStr,
     823             :                                   sal_Int32 nLen,
     824             :                                   rtl_TextEncoding eTextEncoding,
     825             :                                   sal_uInt32 nCvtFlags ) SAL_THROW_EXTERN_C()
     826             : {
     827             :     assert(ppThis);
     828             :     assert(nLen >= 0);
     829             :     rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding,
     830    16659250 :                                nCvtFlags, NULL );
     831    16659248 : }
     832             : 
     833             : /* ----------------------------------------------------------------------- */
     834             : 
     835             : enum StrLifecycle {
     836             :     CANNOT_RETURN,
     837             :     CAN_RETURN = 1
     838             : };
     839             : 
     840             : static oslMutex
     841     1632799 : getInternMutex()
     842             : {
     843             :     static oslMutex pPoolGuard = NULL;
     844     1632799 :     if( !pPoolGuard )
     845             :     {
     846             :         oslMutex pGlobalGuard;
     847         152 :         pGlobalGuard = *osl_getGlobalMutex();
     848         152 :         osl_acquireMutex( pGlobalGuard );
     849         152 :         if( !pPoolGuard )
     850             :         {
     851         152 :             oslMutex p = osl_createMutex();
     852             :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     853         152 :             pPoolGuard = p;
     854             :         }
     855         152 :         osl_releaseMutex( pGlobalGuard );
     856             :     }
     857             :     else
     858             :     {
     859             :         OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     860             :     }
     861             : 
     862     1632799 :     return pPoolGuard;
     863             : }
     864             : 
     865             : /* returns true if we found a dup in the pool */
     866     1017345 : static void rtl_ustring_intern_internal( rtl_uString ** newStr,
     867             :                                          rtl_uString  * str,
     868             :                                          StrLifecycle   can_return )
     869             : {
     870             :     oslMutex pPoolMutex;
     871             : 
     872     1017345 :     pPoolMutex = getInternMutex();
     873             : 
     874     1017345 :     osl_acquireMutex( pPoolMutex );
     875             : 
     876     1017345 :     *newStr = rtl_str_hash_intern (str, can_return);
     877             : 
     878     1017345 :     osl_releaseMutex( pPoolMutex );
     879             : 
     880             :     RTL_LOG_STRING_INTERN_NEW(*newStr, str);
     881             : 
     882     1017345 :     if( can_return && *newStr != str )
     883             :     { /* we dupped, then found a match */
     884      389952 :         rtl_freeMemory( str );
     885             :     }
     886     1017345 : }
     887             : 
     888       38965 : void SAL_CALL rtl_uString_intern( rtl_uString ** newStr,
     889             :                                   rtl_uString  * str) SAL_THROW_EXTERN_C()
     890             : {
     891             :     assert(newStr);
     892             :     assert(str);
     893       38965 :     if (SAL_STRING_IS_INTERN(str))
     894             :     {
     895           1 :         IMPL_RTL_ACQUIRE( str );
     896           1 :         *newStr = str;
     897             :     }
     898             :     else
     899             :     {
     900       38964 :         rtl_uString *pOrg = *newStr;
     901       38964 :         *newStr = NULL;
     902       38964 :         rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN );
     903       38964 :         if (pOrg)
     904           0 :             rtl_uString_release (pOrg);
     905             :     }
     906       38965 : }
     907             : 
     908      966039 : static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding )
     909             : {
     910             :     // FIXME: Maybe we should use a bit flag in the higher bits of the
     911             :     // eTextEncoding value itself to determine the encoding type.  But if we
     912             :     // do, be sure to mask the value in certain places that expect the values
     913             :     // to be numbered serially from 0 and up.  One such place is
     914             :     // Impl_getTextEncodingData().
     915             : 
     916      966039 :     switch ( eTextEncoding )
     917             :     {
     918             :         // 1 to 1 (with no zero elements)
     919             :         case RTL_TEXTENCODING_IBM_437:
     920             :         case RTL_TEXTENCODING_IBM_850:
     921             :         case RTL_TEXTENCODING_IBM_860:
     922             :         case RTL_TEXTENCODING_IBM_861:
     923             :         case RTL_TEXTENCODING_IBM_863:
     924             :         case RTL_TEXTENCODING_IBM_865:
     925           0 :             return len;
     926             :         break;
     927             :     }
     928      966039 :     return 0;
     929             : }
     930             : 
     931      978381 : void SAL_CALL rtl_uString_internConvert( rtl_uString   ** newStr,
     932             :                                          const sal_Char * str,
     933             :                                          sal_Int32        len,
     934             :                                          rtl_TextEncoding eTextEncoding,
     935             :                                          sal_uInt32       convertFlags,
     936             :                                          sal_uInt32     * pInfo )
     937             :     SAL_THROW_EXTERN_C()
     938             : {
     939             :     assert(newStr);
     940             :     assert(len >= 0);
     941             :     rtl_uString *scratch;
     942             : 
     943      978381 :     if (*newStr)
     944             :     {
     945           0 :         rtl_uString_release (*newStr);
     946           0 :         *newStr = NULL;
     947             :     }
     948             : 
     949      978381 :     if ( len < 256 )
     950             :     { // try various optimisations
     951             :         sal_Int32 ulen;
     952      978381 :         if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
     953             :         {
     954             :             int i;
     955             :             rtl_uString *pScratch;
     956             :             pScratch = static_cast< rtl_uString * >(
     957       12342 :                 alloca(sizeof (rtl_uString) + len * sizeof (sal_Unicode)));
     958       86416 :             for (i = 0; i < len; i++)
     959             :             {
     960             :                 /* Check ASCII range */
     961             :                 SAL_WARN_IF( ((unsigned char)str[i]) > 127, "rtl.string",
     962             :                             "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
     963       74074 :                 pScratch->buffer[i] = str[i];
     964             :             }
     965       12342 :             pScratch->length = len;
     966       12342 :             rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
     967       24684 :             return;
     968             :         }
     969      966039 :         else if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 )
     970             :         {
     971             :             rtl_uString *pScratch;
     972             :             rtl_TextToUnicodeConverter hConverter;
     973             :             sal_Size nSrcBytes;
     974             :             sal_uInt32 nInfo;
     975             : 
     976             :             pScratch = static_cast< rtl_uString * >(
     977           0 :                 alloca(
     978           0 :                     sizeof (rtl_uString) + ulen * sizeof (sal_Unicode)));
     979             : 
     980           0 :             hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
     981             :             rtl_convertTextToUnicode(
     982           0 :                 hConverter, 0, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes );
     983           0 :             rtl_destroyTextToUnicodeConverter( hConverter );
     984             : 
     985           0 :             if (pInfo)
     986           0 :                 *pInfo = nInfo;
     987             : 
     988           0 :             pScratch->length = ulen;
     989           0 :             rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
     990           0 :             return;
     991             :         }
     992             : 
     993             :         /* FIXME: we want a nice UTF-8 / alloca shortcut here */
     994             :     }
     995             : 
     996      966039 :     scratch = NULL;
     997             :     rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags,
     998      966039 :                                pInfo );
     999      966039 :     if (!scratch) {
    1000           0 :         return;
    1001             :     }
    1002      966039 :     rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN );
    1003             : }
    1004             : 
    1005             : static void
    1006     7183761 : internRelease (rtl_uString *pThis)
    1007             : {
    1008             :     oslMutex pPoolMutex;
    1009             : 
    1010     7183761 :     rtl_uString *pFree = NULL;
    1011     7183761 :     if ( SAL_STRING_REFCOUNT(
    1012             :              osl_atomic_decrement( &(pThis->refCount) ) ) == 0)
    1013             :     {
    1014             :         RTL_LOG_STRING_INTERN_DELETE(pThis);
    1015      615454 :         pPoolMutex = getInternMutex();
    1016      615454 :         osl_acquireMutex( pPoolMutex );
    1017             : 
    1018      615454 :         rtl_str_hash_remove (pThis);
    1019             : 
    1020             :         /* May have been separately acquired */
    1021      615454 :         if ( SAL_STRING_REFCOUNT(
    1022             :                  osl_atomic_increment( &(pThis->refCount) ) ) == 1 )
    1023             :         {
    1024             :             /* we got the last ref */
    1025      615454 :             pFree = pThis;
    1026             :         }
    1027             :         else /* very unusual */
    1028             :         {
    1029           0 :             internRelease (pThis);
    1030             :         }
    1031             : 
    1032      615454 :         osl_releaseMutex( pPoolMutex );
    1033             :     }
    1034     7183761 :     if (pFree)
    1035      615454 :         rtl_freeMemory (pFree);
    1036     7183761 : }
    1037             : 
    1038  3724359508 : sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints(
    1039             :     rtl_uString const * string, sal_Int32 * indexUtf16,
    1040             :     sal_Int32 incrementCodePoints)
    1041             : {
    1042             :     sal_Int32 n;
    1043             :     sal_Unicode cu;
    1044             :     sal_uInt32 cp;
    1045             :     assert(string != NULL && indexUtf16 != NULL);
    1046  3724359508 :     n = *indexUtf16;
    1047             :     assert(n >= 0 && n <= string->length);
    1048  7636056945 :     while (incrementCodePoints < 0) {
    1049             :         assert(n > 0);
    1050   187337929 :         cu = string->buffer[--n];
    1051   187337933 :         if (rtl::isLowSurrogate(cu) && n != 0 &&
    1052           4 :             rtl::isHighSurrogate(string->buffer[n - 1]))
    1053             :         {
    1054           3 :             --n;
    1055             :         }
    1056   187337929 :         ++incrementCodePoints;
    1057             :     }
    1058             :     assert(n >= 0 && n < string->length);
    1059  3724359508 :     cu = string->buffer[n];
    1060  3724359519 :     if (rtl::isHighSurrogate(cu) && string->length - n >= 2 &&
    1061          11 :         rtl::isLowSurrogate(string->buffer[n + 1]))
    1062             :     {
    1063          11 :         cp = rtl::combineSurrogates(cu, string->buffer[n + 1]);
    1064             :     } else {
    1065  3724359497 :         cp = cu;
    1066             :     }
    1067  9103500791 :     while (incrementCodePoints > 0) {
    1068             :         assert(n < string->length);
    1069  1654781775 :         cu = string->buffer[n++];
    1070  1654781783 :         if (rtl::isHighSurrogate(cu) && n != string->length &&
    1071           8 :             rtl::isLowSurrogate(string->buffer[n]))
    1072             :         {
    1073           8 :             ++n;
    1074             :         }
    1075  1654781775 :         --incrementCodePoints;
    1076             :     }
    1077             :     assert(n >= 0 && n <= string->length);
    1078  3724359508 :     *indexUtf16 = n;
    1079  3724359508 :     return cp;
    1080             : }
    1081             : 
    1082    24436015 : sal_Bool rtl_convertStringToUString(
    1083             :     rtl_uString ** target, char const * source, sal_Int32 length,
    1084             :     rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C()
    1085             : {
    1086             :     assert(target);
    1087             :     assert(length >= 0);
    1088             :     sal_uInt32 info;
    1089    24436015 :     rtl_string2UString_status(target, source, length, encoding, flags, &info);
    1090    24436016 :     return (info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0;
    1091             : }
    1092             : 
    1093   171134369 : void rtl_uString_newReplaceFirst(
    1094             :     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
    1095             :     rtl_uString const * to, sal_Int32 * index) SAL_THROW_EXTERN_C()
    1096             : {
    1097             :     assert(str != 0);
    1098             :     assert(index != 0);
    1099             :     assert(*index >= 0 && *index <= str->length);
    1100             :     assert(from != 0);
    1101             :     assert(to != 0);
    1102             :     sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
    1103   171134369 :         str->buffer + *index, str->length - *index, from->buffer, from->length);
    1104   171134369 :     if (i == -1) {
    1105   171110757 :         rtl_uString_assign(newStr, str);
    1106             :     } else {
    1107             :         assert(i <= str->length - *index);
    1108       23612 :         i += *index;
    1109             :         assert(from->length <= str->length);
    1110       23612 :         if (str->length - from->length > SAL_MAX_INT32 - to->length) {
    1111           0 :             std::abort();
    1112             :         }
    1113       23612 :         sal_Int32 n = str->length - from->length + to->length;
    1114       23612 :         rtl_uString_acquire(str); // in case *newStr == str
    1115       23612 :         rtl_uString_new_WithLength(newStr, n);
    1116       23612 :         if (n != 0) {
    1117       23611 :             (*newStr)->length = n;
    1118             :             assert(i >= 0 && i < str->length);
    1119             :             memcpy(
    1120       23611 :                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
    1121             :             memcpy(
    1122       23611 :                 (*newStr)->buffer + i, to->buffer,
    1123       47222 :                 to->length * sizeof (sal_Unicode));
    1124             :             memcpy(
    1125       23611 :                 (*newStr)->buffer + i + to->length,
    1126       23611 :                 str->buffer + i + from->length,
    1127       47222 :                 (str->length - i - from->length) * sizeof (sal_Unicode));
    1128             :         }
    1129       23612 :         rtl_uString_release(str);
    1130             :     }
    1131   171134369 :     *index = i;
    1132   171134369 : }
    1133             : 
    1134       35928 : void rtl_uString_newReplaceFirstAsciiL(
    1135             :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1136             :     sal_Int32 fromLength, rtl_uString const * to, sal_Int32 * index)
    1137             :     SAL_THROW_EXTERN_C()
    1138             : {
    1139             :     assert(str != 0);
    1140             :     assert(index != 0);
    1141             :     assert(*index >= 0 && *index <= str->length);
    1142             :     assert(fromLength >= 0);
    1143             :     assert(to != 0);
    1144             :     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
    1145       35928 :         str->buffer + *index, str->length - *index, from, fromLength);
    1146       35928 :     if (i == -1) {
    1147       17740 :         rtl_uString_assign(newStr, str);
    1148             :     } else {
    1149             :         assert(i <= str->length - *index);
    1150       18188 :         i += *index;
    1151             :         assert(fromLength <= str->length);
    1152       18188 :         if (str->length - fromLength > SAL_MAX_INT32 - to->length) {
    1153           0 :             std::abort();
    1154             :         }
    1155       18188 :         sal_Int32 n = str->length - fromLength + to->length;
    1156       18188 :         rtl_uString_acquire(str); // in case *newStr == str
    1157       18188 :         if (n != 0) {
    1158       18188 :             rtl_uString_new_WithLength(newStr, n);
    1159       18188 :             (*newStr)->length = n;
    1160             :             assert(i >= 0 && i < str->length);
    1161             :             memcpy(
    1162       18188 :                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
    1163             :             memcpy(
    1164       18188 :                 (*newStr)->buffer + i, to->buffer,
    1165       36376 :                 to->length * sizeof (sal_Unicode));
    1166             :             memcpy(
    1167       18188 :                 (*newStr)->buffer + i + to->length,
    1168       18188 :                 str->buffer + i + fromLength,
    1169       36376 :                 (str->length - i - fromLength) * sizeof (sal_Unicode));
    1170             :         }
    1171       18188 :         rtl_uString_release(str);
    1172             :     }
    1173       35928 :     *index = i;
    1174       35928 : }
    1175             : 
    1176       51001 : void rtl_uString_newReplaceFirstAsciiLAsciiL(
    1177             :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1178             :     sal_Int32 fromLength, char const * to, sal_Int32 toLength,
    1179             :     sal_Int32 * index) SAL_THROW_EXTERN_C()
    1180             : {
    1181             :     assert(str != 0);
    1182             :     assert(index != 0);
    1183             :     assert(*index >= 0 && *index <= str->length);
    1184             :     assert(fromLength >= 0);
    1185             :     assert(to != 0);
    1186             :     assert(toLength >= 0);
    1187             :     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
    1188       51001 :         str->buffer + *index, str->length - *index, from, fromLength);
    1189       51001 :     if (i == -1) {
    1190       13612 :         rtl_uString_assign(newStr, str);
    1191             :     } else {
    1192             :         assert(i <= str->length - *index);
    1193       37389 :         i += *index;
    1194             :         assert(fromLength <= str->length);
    1195       37389 :         if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
    1196           0 :             std::abort();
    1197             :         }
    1198       37389 :         sal_Int32 n = str->length - fromLength + toLength;
    1199       37389 :         rtl_uString_acquire(str); // in case *newStr == str
    1200       37389 :         if (n != 0) {
    1201       37389 :             rtl_uString_new_WithLength(newStr, n);
    1202       37389 :             (*newStr)->length = n;
    1203             :             assert(i >= 0 && i < str->length);
    1204             :             memcpy(
    1205       37389 :                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
    1206      215541 :             for (sal_Int32 j = 0; j != toLength; ++j) {
    1207             :                 assert(static_cast< unsigned char >(to[j]) <= 0x7F);
    1208      178152 :                 (*newStr)->buffer[i + j] = to[j];
    1209             :             }
    1210             :             memcpy(
    1211       37389 :                 (*newStr)->buffer + i + toLength,
    1212       37389 :                 str->buffer + i + fromLength,
    1213       74778 :                 (str->length - i - fromLength) * sizeof (sal_Unicode));
    1214             :         }
    1215       37389 :         rtl_uString_release(str);
    1216             :     }
    1217       51001 :     *index = i;
    1218       51001 : }
    1219             : 
    1220           0 : void rtl_uString_newReplaceAll(
    1221             :     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
    1222             :     rtl_uString const * to) SAL_THROW_EXTERN_C()
    1223             : {
    1224           0 :     rtl_uString_newReplaceAllFromIndex( newStr, str, from, to, 0 );
    1225           0 : }
    1226             : 
    1227   171109973 : void rtl_uString_newReplaceAllFromIndex(
    1228             :     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
    1229             :     rtl_uString const * to, sal_Int32 fromIndex) SAL_THROW_EXTERN_C()
    1230             : {
    1231             :     assert(to != 0);
    1232             :     assert(fromIndex >= 0 && fromIndex <= str->length);
    1233   171109973 :     rtl_uString_assign(newStr, str);
    1234   171132342 :     for (sal_Int32 i = fromIndex;; i += to->length) {
    1235   171132342 :         rtl_uString_newReplaceFirst(newStr, *newStr, from, to, &i);
    1236   171132342 :         if (i == -1) {
    1237   171109973 :             break;
    1238             :         }
    1239       22369 :     }
    1240   171109973 : }
    1241             : 
    1242       16259 : void rtl_uString_newReplaceAllAsciiL(
    1243             :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1244             :     sal_Int32 fromLength, rtl_uString const * to) SAL_THROW_EXTERN_C()
    1245             : {
    1246             :     assert(to != 0);
    1247       16259 :     rtl_uString_assign(newStr, str);
    1248       18009 :     for (sal_Int32 i = 0;; i += to->length) {
    1249             :         rtl_uString_newReplaceFirstAsciiL(
    1250       18009 :             newStr, *newStr, from, fromLength, to, &i);
    1251       18009 :         if (i == -1) {
    1252       16259 :             break;
    1253             :         }
    1254        1750 :     }
    1255       16259 : }
    1256             : 
    1257       13606 : void rtl_uString_newReplaceAllAsciiLAsciiL(
    1258             :     rtl_uString ** newStr, rtl_uString * str, char const * from,
    1259             :     sal_Int32 fromLength, char const * to, sal_Int32 toLength)
    1260             :     SAL_THROW_EXTERN_C()
    1261             : {
    1262             :     assert(toLength >= 0);
    1263       13606 :     rtl_uString_assign(newStr, str);
    1264       50293 :     for (sal_Int32 i = 0;; i += toLength) {
    1265             :         rtl_uString_newReplaceFirstAsciiLAsciiL(
    1266       50293 :             newStr, *newStr, from, fromLength, to, toLength, &i);
    1267       50293 :         if (i == -1) {
    1268       13606 :             break;
    1269             :         }
    1270       36687 :     }
    1271       13606 : }
    1272             : 
    1273             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11