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

Generated by: LCOV version 1.10