LCOV - code coverage report
Current view: top level - xpcom/string - nsStringObsolete.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 178 347 51.3 %
Date: 2017-07-14 16:53:18 Functions: 28 49 57.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsString.h"
       8             : 
       9             : 
      10             : /**
      11             :  * nsTString obsolete API support
      12             :  */
      13             : 
      14             : #if MOZ_STRING_WITH_OBSOLETE_API
      15             : 
      16             : #include "nsDependentString.h"
      17             : #include "nsDependentSubstring.h"
      18             : #include "nsReadableUtils.h"
      19             : #include "nsCRT.h"
      20             : #include "nsUTF8Utils.h"
      21             : #include "prdtoa.h"
      22             : 
      23             : /* ***** BEGIN RICKG BLOCK *****
      24             :  *
      25             :  * NOTE: This section of code was extracted from rickg's bufferRoutines.h file.
      26             :  *       For the most part it remains unmodified.  We want to eliminate (or at
      27             :  *       least clean up) this code at some point.  If you find the formatting
      28             :  *       in this section somewhat inconsistent, don't blame me! ;-)
      29             :  */
      30             : 
      31             : // avoid STDC's tolower since it may do weird things with non-ASCII bytes
      32             : inline char
      33         382 : ascii_tolower(char aChar)
      34             : {
      35         382 :   if (aChar >= 'A' && aChar <= 'Z')
      36           0 :     return aChar + ('a' - 'A');
      37         382 :   return aChar;
      38             : }
      39             : 
      40             : //-----------------------------------------------------------------------------
      41             : //
      42             : //  This set of methods is used to search a buffer looking for a char.
      43             : //
      44             : 
      45             : 
      46             : /**
      47             :  *  This methods cans the given buffer for the given char
      48             :  *
      49             :  *  @update  gess 02/17/00
      50             :  *  @param   aDest is the buffer to be searched
      51             :  *  @param   aDestLength is the size (in char-units, not bytes) of the buffer
      52             :  *  @param   anOffset is the start pos to begin searching
      53             :  *  @param   aChar is the target character we're looking for
      54             :  *  @param   aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
      55             :  *  @return  index of pos if found, else -1 (kNotFound)
      56             :  */
      57             : static int32_t
      58        3264 : FindChar1(const char* aDest,uint32_t aDestLength,int32_t anOffset,const char16_t aChar,int32_t aCount) {
      59             : 
      60        3264 :   if(anOffset < 0)
      61           0 :     anOffset=0;
      62             : 
      63        3264 :   if(aCount < 0)
      64           0 :     aCount = (int32_t)aDestLength;
      65             : 
      66        3264 :   if((aChar < 256) && (0 < aDestLength) && ((uint32_t)anOffset < aDestLength)) {
      67             : 
      68             :     //We'll only search if the given aChar is within the normal ascii a range,
      69             :     //(Since this string is definitely within the ascii range).
      70             : 
      71        3215 :     if(0<aCount) {
      72             : 
      73        3215 :       const char* left= aDest+anOffset;
      74        3215 :       const char* last= left+aCount;
      75        3215 :       const char* max = aDest+aDestLength;
      76        3215 :       const char* end = (last<max) ? last : max;
      77             : 
      78        3215 :       int32_t theMax = end-left;
      79        3215 :       if(0<theMax) {
      80             : 
      81        3215 :         unsigned char theChar = (unsigned char) aChar;
      82        3215 :         const char* result=(const char*)memchr(left, (int)theChar, theMax);
      83             : 
      84        3215 :         if(result)
      85         293 :           return result-aDest;
      86             : 
      87             :       }
      88             :     }
      89             :   }
      90             : 
      91        2971 :   return kNotFound;
      92             : }
      93             : 
      94             : 
      95             : /**
      96             :  *  This methods cans the given buffer for the given char
      97             :  *
      98             :  *  @update  gess 3/25/98
      99             :  *  @param   aDest is the buffer to be searched
     100             :  *  @param   aDestLength is the size (in char-units, not bytes) of the buffer
     101             :  *  @param   anOffset is the start pos to begin searching
     102             :  *  @param   aChar is the target character we're looking for
     103             :  *  @param   aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
     104             :  *  @return  index of pos if found, else -1 (kNotFound)
     105             :  */
     106             : static int32_t
     107           0 : FindChar2(const char16_t* aDest,uint32_t aDestLength,int32_t anOffset,const char16_t aChar,int32_t aCount) {
     108             : 
     109           0 :   if(anOffset < 0)
     110           0 :     anOffset=0;
     111             : 
     112           0 :   if(aCount < 0)
     113           0 :     aCount = (int32_t)aDestLength;
     114             : 
     115           0 :   if((0<aDestLength) && ((uint32_t)anOffset < aDestLength)) {
     116             : 
     117           0 :     if(0<aCount) {
     118             : 
     119           0 :       const char16_t* root = aDest;
     120           0 :       const char16_t* left = root+anOffset;
     121           0 :       const char16_t* last = left+aCount;
     122           0 :       const char16_t* max  = root+aDestLength;
     123           0 :       const char16_t* end  = (last<max) ? last : max;
     124             : 
     125           0 :       while(left<end){
     126             : 
     127           0 :         if(*left==aChar)
     128           0 :           return (left-root);
     129             : 
     130           0 :         ++left;
     131             :       }
     132             :     }
     133             :   }
     134             : 
     135           0 :   return kNotFound;
     136             : }
     137             : 
     138             : 
     139             : /**
     140             :  *  This methods cans the given buffer (in reverse) for the given char
     141             :  *
     142             :  *  @update  gess 02/17/00
     143             :  *  @param   aDest is the buffer to be searched
     144             :  *  @param   aDestLength is the size (in char-units, not bytes) of the buffer
     145             :  *  @param   anOffset is the start pos to begin searching
     146             :  *  @param   aChar is the target character we're looking for
     147             :  *  @param   aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
     148             :  *  @return  index of pos if found, else -1 (kNotFound)
     149             :  */
     150             : 
     151             : static int32_t
     152         144 : RFindChar1(const char* aDest,uint32_t aDestLength,int32_t anOffset,const char16_t aChar,int32_t aCount) {
     153             : 
     154         144 :   if(anOffset < 0)
     155         144 :     anOffset=(int32_t)aDestLength-1;
     156             : 
     157         144 :   if(aCount < 0)
     158         144 :     aCount = int32_t(aDestLength);
     159             : 
     160         144 :   if((aChar<256) && (0 < aDestLength) && ((uint32_t)anOffset < aDestLength)) {
     161             : 
     162             :     //We'll only search if the given aChar is within the normal ascii a range,
     163             :     //(Since this string is definitely within the ascii range).
     164             : 
     165         144 :     if(0 < aCount) {
     166             : 
     167         144 :       const char* rightmost = aDest + anOffset;
     168         144 :       const char* min       = rightmost - aCount + 1;
     169         144 :       const char* leftmost  = (min<aDest) ? aDest: min;
     170             : 
     171         144 :       char theChar=(char)aChar;
     172        4806 :       while(leftmost <= rightmost){
     173             : 
     174        2389 :         if((*rightmost) == theChar)
     175          58 :           return rightmost - aDest;
     176             : 
     177        2331 :         --rightmost;
     178             :       }
     179             :     }
     180             :   }
     181             : 
     182          86 :   return kNotFound;
     183             : }
     184             : 
     185             : 
     186             : /**
     187             :  *  This methods cans the given buffer for the given char
     188             :  *
     189             :  *  @update  gess 3/25/98
     190             :  *  @param   aDest is the buffer to be searched
     191             :  *  @param   aDestLength is the size (in char-units, not bytes) of the buffer
     192             :  *  @param   anOffset is the start pos to begin searching
     193             :  *  @param   aChar is the target character we're looking for
     194             :  *  @param   aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
     195             :  *  @return  index of pos if found, else -1 (kNotFound)
     196             :  */
     197             : static int32_t
     198           0 : RFindChar2(const char16_t* aDest,uint32_t aDestLength,int32_t anOffset,const char16_t aChar,int32_t aCount) {
     199             : 
     200           0 :   if(anOffset < 0)
     201           0 :     anOffset=(int32_t)aDestLength-1;
     202             : 
     203           0 :   if(aCount < 0)
     204           0 :     aCount = int32_t(aDestLength);
     205             : 
     206           0 :   if((0 < aDestLength) && ((uint32_t)anOffset < aDestLength)) {
     207             : 
     208           0 :     if(0 < aCount) {
     209             : 
     210           0 :       const char16_t* root      = aDest;
     211           0 :       const char16_t* rightmost = root + anOffset;
     212           0 :       const char16_t* min       = rightmost - aCount + 1;
     213           0 :       const char16_t* leftmost  = (min<root) ? root: min;
     214             : 
     215           0 :       while(leftmost <= rightmost){
     216             : 
     217           0 :         if((*rightmost) == aChar)
     218           0 :           return rightmost - root;
     219             : 
     220           0 :         --rightmost;
     221             :       }
     222             :     }
     223             :   }
     224             : 
     225           0 :   return kNotFound;
     226             : }
     227             : 
     228             : //-----------------------------------------------------------------------------
     229             : //
     230             : //  This set of methods is used to compare one buffer onto another.  The
     231             : //  functions are differentiated by the size of source and dest character
     232             : //  sizes.  WARNING: Your destination buffer MUST be big enough to hold all the
     233             : //  source bytes.  We don't validate these ranges here (this should be done in
     234             : //  higher level routines).
     235             : //
     236             : 
     237             : 
     238             : /**
     239             :  * This method compares the data in one buffer with another
     240             :  * @update      gess 01/04/99
     241             :  * @param   aStr1 is the first buffer to be compared
     242             :  * @param   aStr2 is the 2nd buffer to be compared
     243             :  * @param   aCount is the number of chars to compare
     244             :  * @param   aIgnoreCase tells us whether to use a case-sensitive comparison
     245             :  * @return  -1,0,1 depending on <,==,>
     246             :  */
     247             : static
     248             : #ifdef __SUNPRO_CC
     249             : inline
     250             : #endif /* __SUNPRO_CC */
     251             : int32_t
     252      228240 : Compare1To1(const char* aStr1,const char* aStr2,uint32_t aCount,bool aIgnoreCase) {
     253      228240 :   int32_t result=0;
     254      228240 :   if(aIgnoreCase)
     255           2 :     result=int32_t(PL_strncasecmp(aStr1, aStr2, aCount));
     256             :   else
     257      228238 :     result=nsCharTraits<char>::compare(aStr1,aStr2,aCount);
     258             : 
     259             :   // alien comparisons may return out-of-bound answers
     260             :   //  instead of the -1, 0, 1 expected by most clients
     261      228240 :   if ( result < -1 )
     262       42995 :     result = -1;
     263      185245 :   else if ( result > 1 )
     264      182091 :     result = 1;
     265      228240 :   return result;
     266             : }
     267             : 
     268             : /**
     269             :  * This method compares the data in one buffer with another
     270             :  * @update      gess 01/04/99
     271             :  * @param   aStr1 is the first buffer to be compared
     272             :  * @param   aStr2 is the 2nd buffer to be compared
     273             :  * @param   aCount is the number of chars to compare
     274             :  * @param   aIgnoreCase tells us whether to use a case-sensitive comparison
     275             :  * @return  -1,0,1 depending on <,==,>
     276             :  */
     277             : static
     278             : #ifdef __SUNPRO_CC
     279             : inline
     280             : #endif /* __SUNPRO_CC */
     281             : int32_t
     282          70 : Compare2To2(const char16_t* aStr1,const char16_t* aStr2,uint32_t aCount){
     283             :   int32_t result;
     284             : 
     285          70 :   if ( aStr1 && aStr2 )
     286          70 :     result = nsCharTraits<char16_t>::compare(aStr1, aStr2, aCount);
     287             : 
     288             :   // The following cases are rare and survivable caller errors.
     289             :   //  Two null pointers are equal, but any string, even 0 length
     290             :   //  is greater than a null pointer.  It might not really matter,
     291             :   //  but we pick something reasonable anyway.
     292           0 :   else if ( !aStr1 && !aStr2 )
     293           0 :     result = 0;
     294           0 :   else if ( aStr1 )
     295           0 :     result = 1;
     296             :   else
     297           0 :     result = -1;
     298             : 
     299             :   // alien comparisons may give answers outside the -1, 0, 1 expected by callers
     300          70 :   if ( result < -1 )
     301          27 :     result = -1;
     302          43 :   else if ( result > 1 )
     303          35 :     result = 1;
     304          70 :   return result;
     305             : }
     306             : 
     307             : 
     308             : /**
     309             :  * This method compares the data in one buffer with another
     310             :  * @update      gess 01/04/99
     311             :  * @param   aStr1 is the first buffer to be compared
     312             :  * @param   aStr2 is the 2nd buffer to be compared
     313             :  * @param   aCount is the number of chars to compare
     314             :  * @param   aIgnoreCase tells us whether to use a case-sensitive comparison
     315             :  * @return  -1,0,1 depending on <,==,>
     316             :  */
     317             : static
     318             : #ifdef __SUNPRO_CC
     319             : inline
     320             : #endif /* __SUNPRO_CC */
     321             : int32_t
     322         336 : Compare2To1(const char16_t* aStr1,const char* aStr2,uint32_t aCount,bool aIgnoreCase){
     323         336 :   const char16_t* s1 = aStr1;
     324         336 :   const char *s2 = aStr2;
     325             : 
     326         336 :   if (aStr1 && aStr2) {
     327         336 :     if (aCount != 0) {
     328          30 :       do {
     329             : 
     330         356 :         char16_t c1 = *s1++;
     331         356 :         char16_t c2 = char16_t((unsigned char)*s2++);
     332             : 
     333         356 :         if (c1 != c2) {
     334             : #ifdef DEBUG
     335             :           // we won't warn on c1>=128 (the 2-byte value) because often
     336             :           // it is just fine to compare an constant, ascii value (i.e. "body")
     337             :           // against some non-ascii value (i.e. a unicode string that
     338             :           // was downloaded from a web page)
     339         326 :           if (aIgnoreCase && c2>=128)
     340           0 :             NS_WARNING("got a non-ASCII string, but we can't do an accurate case conversion!");
     341             : #endif
     342             : 
     343             :           // can't do case conversion on characters out of our range
     344         326 :           if (aIgnoreCase && c1<128 && c2<128) {
     345             : 
     346         191 :             c1 = ascii_tolower(char(c1));
     347         191 :             c2 = ascii_tolower(char(c2));
     348             : 
     349         191 :             if (c1 == c2) continue;
     350             :           }
     351             : 
     352         326 :           if (c1 < c2) return -1;
     353         209 :           return 1;
     354             :         }
     355             :       } while (--aCount);
     356             :     }
     357             :   }
     358          10 :   return 0;
     359             : }
     360             : 
     361             : 
     362             : /**
     363             :  * This method compares the data in one buffer with another
     364             :  * @update      gess 01/04/99
     365             :  * @param   aStr1 is the first buffer to be compared
     366             :  * @param   aStr2 is the 2nd buffer to be compared
     367             :  * @param   aCount is the number of chars to compare
     368             :  * @param   aIgnoreCase tells us whether to use a case-sensitive comparison
     369             :  * @return  -1,0,1 depending on <,==,>
     370             :  */
     371             : inline int32_t
     372             : Compare1To2(const char* aStr1,const char16_t* aStr2,uint32_t aCount,bool aIgnoreCase){
     373             :   return Compare2To1(aStr2, aStr1, aCount, aIgnoreCase) * -1;
     374             : }
     375             : 
     376             : 
     377             : //-----------------------------------------------------------------------------
     378             : //
     379             : //  This set of methods is used compress char sequences in a buffer...
     380             : //
     381             : 
     382             : 
     383             : /**
     384             :  * This method compresses duplicate runs of a given char from the given buffer
     385             :  *
     386             :  * @update      rickg 03.23.2000
     387             :  * @param   aString is the buffer to be manipulated
     388             :  * @param   aLength is the length of the buffer
     389             :  * @param   aSet tells us which chars to compress from given buffer
     390             :  * @param   aEliminateLeading tells us whether to strip chars from the start of the buffer
     391             :  * @param   aEliminateTrailing tells us whether to strip chars from the start of the buffer
     392             :  * @return  the new length of the given buffer
     393             :  */
     394             : static int32_t
     395           0 : CompressChars1(char* aString,uint32_t aLength,const char* aSet){
     396             : 
     397           0 :   char*  from = aString;
     398           0 :   char*  end =  aString + aLength;
     399           0 :   char*  to = from;
     400             : 
     401             :   //this code converts /n, /t, /r into normal space ' ';
     402             :   //it also compresses runs of whitespace down to a single char...
     403           0 :   if(aSet && aString && (0 < aLength)){
     404           0 :     uint32_t aSetLen=strlen(aSet);
     405             : 
     406           0 :     while (from < end) {
     407           0 :       char theChar = *from++;
     408             : 
     409           0 :       *to++=theChar; //always copy this char...
     410             : 
     411           0 :       if((kNotFound!=FindChar1(aSet,aSetLen,0,theChar,aSetLen))){
     412           0 :         while (from < end) {
     413           0 :           theChar = *from++;
     414           0 :           if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen)){
     415           0 :             *to++ = theChar;
     416           0 :             break;
     417             :           }
     418             :         } //while
     419             :       } //if
     420             :     } //if
     421           0 :     *to = 0;
     422             :   }
     423           0 :   return to - aString;
     424             : }
     425             : 
     426             : 
     427             : 
     428             : /**
     429             :  * This method compresses duplicate runs of a given char from the given buffer
     430             :  *
     431             :  * @update      rickg 03.23.2000
     432             :  * @param   aString is the buffer to be manipulated
     433             :  * @param   aLength is the length of the buffer
     434             :  * @param   aSet tells us which chars to compress from given buffer
     435             :  * @param   aEliminateLeading tells us whether to strip chars from the start of the buffer
     436             :  * @param   aEliminateTrailing tells us whether to strip chars from the start of the buffer
     437             :  * @return  the new length of the given buffer
     438             :  */
     439             : static int32_t
     440           0 : CompressChars2(char16_t* aString,uint32_t aLength,const char* aSet) {
     441             : 
     442           0 :   char16_t*  from = aString;
     443           0 :   char16_t*  end =  from + aLength;
     444           0 :   char16_t*  to = from;
     445             : 
     446             :   //this code converts /n, /t, /r into normal space ' ';
     447             :   //it also compresses runs of whitespace down to a single char...
     448           0 :   if(aSet && aString && (0 < aLength)){
     449           0 :     uint32_t aSetLen=strlen(aSet);
     450             : 
     451           0 :     while (from < end) {
     452           0 :       char16_t theChar = *from++;
     453             : 
     454           0 :       *to++=theChar; //always copy this char...
     455             : 
     456           0 :       if((theChar<256) && (kNotFound!=FindChar1(aSet,aSetLen,0,theChar,aSetLen))){
     457           0 :         while (from < end) {
     458           0 :           theChar = *from++;
     459           0 :           if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen)){
     460           0 :             *to++ = theChar;
     461           0 :             break;
     462             :           }
     463             :         } //while
     464             :       } //if
     465             :     } //if
     466           0 :     *to = 0;
     467             :   }
     468           0 :   return to - (char16_t*)aString;
     469             : }
     470             : 
     471             : /**
     472             :  * This method strips chars in a given set from the given buffer
     473             :  *
     474             :  * @update      gess 01/04/99
     475             :  * @param   aString is the buffer to be manipulated
     476             :  * @param   aLength is the length of the buffer
     477             :  * @param   aSet tells us which chars to compress from given buffer
     478             :  * @param   aEliminateLeading tells us whether to strip chars from the start of the buffer
     479             :  * @param   aEliminateTrailing tells us whether to strip chars from the start of the buffer
     480             :  * @return  the new length of the given buffer
     481             :  */
     482             : static int32_t
     483           2 : StripChars1(char* aString,uint32_t aLength,const char* aSet) {
     484             : 
     485             :   // XXX(darin): this code should defer writing until necessary.
     486             : 
     487           2 :   char*  to   = aString;
     488           2 :   char*  from = aString-1;
     489           2 :   char*  end  = aString + aLength;
     490             : 
     491           2 :   if(aSet && aString && (0 < aLength)){
     492           2 :     uint32_t aSetLen=strlen(aSet);
     493          30 :     while (++from < end) {
     494          14 :       char theChar = *from;
     495          14 :       if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen)){
     496          14 :         *to++ = theChar;
     497             :       }
     498             :     }
     499           2 :     *to = 0;
     500             :   }
     501           2 :   return to - (char*)aString;
     502             : }
     503             : 
     504             : 
     505             : /**
     506             :  * This method strips chars in a given set from the given buffer
     507             :  *
     508             :  * @update      gess 01/04/99
     509             :  * @param   aString is the buffer to be manipulated
     510             :  * @param   aLength is the length of the buffer
     511             :  * @param   aSet tells us which chars to compress from given buffer
     512             :  * @param   aEliminateLeading tells us whether to strip chars from the start of the buffer
     513             :  * @param   aEliminateTrailing tells us whether to strip chars from the start of the buffer
     514             :  * @return  the new length of the given buffer
     515             :  */
     516             : static int32_t
     517           0 : StripChars2(char16_t* aString,uint32_t aLength,const char* aSet) {
     518             : 
     519             :   // XXX(darin): this code should defer writing until necessary.
     520             : 
     521           0 :   char16_t*  to   = aString;
     522           0 :   char16_t*  from = aString-1;
     523           0 :   char16_t*  end  = to + aLength;
     524             : 
     525           0 :   if(aSet && aString && (0 < aLength)){
     526           0 :     uint32_t aSetLen=strlen(aSet);
     527           0 :     while (++from < end) {
     528           0 :       char16_t theChar = *from;
     529             :       //Note the test for ascii range below. If you have a real unicode char,
     530             :       //and you're searching for chars in the (given) ascii string, there's no
     531             :       //point in doing the real search since it's out of the ascii range.
     532           0 :       if((255<theChar) || (kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen))){
     533           0 :         *to++ = theChar;
     534             :       }
     535             :     }
     536           0 :     *to = 0;
     537             :   }
     538           0 :   return to - (char16_t*)aString;
     539             : }
     540             : 
     541             : /* ***** END RICKG BLOCK ***** */
     542             : 
     543             : // This function is used to implement FindCharInSet and friends
     544             : template <class CharT>
     545             : #ifndef __SUNPRO_CC
     546             : static
     547             : #endif /* !__SUNPRO_CC */
     548             : CharT
     549         336 : GetFindInSetFilter( const CharT* set)
     550             : {
     551         336 :   CharT filter = ~CharT(0); // All bits set
     552        3506 :   while (*set) {
     553        1585 :     filter &= ~(*set);
     554        1585 :     ++set;
     555             :   }
     556         336 :   return filter;
     557             : }
     558             : 
     559             : // This template class is used by our code to access rickg's buffer routines.
     560             : template <class CharT> struct nsBufferRoutines {};
     561             : 
     562             : template <>
     563             : struct nsBufferRoutines<char>
     564             : {
     565             :   static
     566      228240 :   int32_t compare( const char* a, const char* b, uint32_t max, bool ic )
     567             :   {
     568      228240 :     return Compare1To1(a, b, max, ic);
     569             :   }
     570             : 
     571             :   static
     572             :   int32_t compare( const char* a, const char16_t* b, uint32_t max, bool ic )
     573             :   {
     574             :     return Compare1To2(a, b, max, ic);
     575             :   }
     576             : 
     577             :   static
     578             :   int32_t find_char( const char* s, uint32_t max, int32_t offset, const char16_t c, int32_t count )
     579             :   {
     580             :     return FindChar1(s, max, offset, c, count);
     581             :   }
     582             : 
     583             :   static
     584         144 :   int32_t rfind_char( const char* s, uint32_t max, int32_t offset, const char16_t c, int32_t count )
     585             :   {
     586         144 :     return RFindChar1(s, max, offset, c, count);
     587             :   }
     588             : 
     589             :   static
     590         323 :   char get_find_in_set_filter( const char* set )
     591             :   {
     592         323 :     return GetFindInSetFilter(set);
     593             :   }
     594             : 
     595             :   static
     596           2 :   int32_t strip_chars( char* s, uint32_t len, const char* set )
     597             :   {
     598           2 :     return StripChars1(s, len, set);
     599             :   }
     600             : 
     601             :   static
     602             :   int32_t compress_chars( char* s, uint32_t len, const char* set )
     603             :   {
     604             :     return CompressChars1(s, len, set);
     605             :   }
     606             : };
     607             : 
     608             : template <>
     609             : struct nsBufferRoutines<char16_t>
     610             : {
     611             :   static
     612          70 :   int32_t compare( const char16_t* a, const char16_t* b, uint32_t max, bool ic )
     613             :   {
     614          70 :     NS_ASSERTION(!ic, "no case-insensitive compare here");
     615          70 :     return Compare2To2(a, b, max);
     616             :   }
     617             : 
     618             :   static
     619         336 :   int32_t compare( const char16_t* a, const char* b, uint32_t max, bool ic )
     620             :   {
     621         336 :     return Compare2To1(a, b, max, ic);
     622             :   }
     623             : 
     624             :   static
     625             :   int32_t find_char( const char16_t* s, uint32_t max, int32_t offset, const char16_t c, int32_t count )
     626             :   {
     627             :     return FindChar2(s, max, offset, c, count);
     628             :   }
     629             : 
     630             :   static
     631           0 :   int32_t rfind_char( const char16_t* s, uint32_t max, int32_t offset, const char16_t c, int32_t count )
     632             :   {
     633           0 :     return RFindChar2(s, max, offset, c, count);
     634             :   }
     635             : 
     636             :   static
     637           0 :   char16_t get_find_in_set_filter( const char16_t* set )
     638             :   {
     639           0 :     return GetFindInSetFilter(set);
     640             :   }
     641             : 
     642             :   static
     643          13 :   char16_t get_find_in_set_filter( const char* set )
     644             :   {
     645          13 :     return (~char16_t(0)^~char(0)) | GetFindInSetFilter(set);
     646             :   }
     647             : 
     648             :   static
     649           0 :   int32_t strip_chars( char16_t* s, uint32_t max, const char* set )
     650             :   {
     651           0 :     return StripChars2(s, max, set);
     652             :   }
     653             : 
     654             :   static
     655             :   int32_t compress_chars( char16_t* s, uint32_t len, const char* set )
     656             :   {
     657             :     return CompressChars2(s, len, set);
     658             :   }
     659             : };
     660             : 
     661             : //-----------------------------------------------------------------------------
     662             : 
     663             : template <class L, class R>
     664             : #ifndef __SUNPRO_CC
     665             : static
     666             : #endif /* !__SUNPRO_CC */
     667             : int32_t
     668        2522 : FindSubstring( const L* big, uint32_t bigLen,
     669             :                const R* little, uint32_t littleLen,
     670             :                bool ignoreCase )
     671             : {
     672        2522 :   if (littleLen > bigLen)
     673           3 :     return kNotFound;
     674             : 
     675        2519 :   int32_t i, max = int32_t(bigLen - littleLen);
     676      229434 :   for (i=0; i<=max; ++i, ++big)
     677             :   {
     678      226934 :     if (nsBufferRoutines<L>::compare(big, little, littleLen, ignoreCase) == 0)
     679          19 :       return i;
     680             :   }
     681             : 
     682        2500 :   return kNotFound;
     683             : }
     684             : 
     685             : template <class L, class R>
     686             : #ifndef __SUNPRO_CC
     687             : static
     688             : #endif /* !__SUNPRO_CC */
     689             : int32_t
     690          49 : RFindSubstring( const L* big, uint32_t bigLen,
     691             :                 const R* little, uint32_t littleLen,
     692             :                 bool ignoreCase )
     693             : {
     694          49 :   if (littleLen > bigLen)
     695           0 :     return kNotFound;
     696             : 
     697          49 :   int32_t i, max = int32_t(bigLen - littleLen);
     698             : 
     699          49 :   const L* iter = big + max;
     700         746 :   for (i=max; iter >= big; --i, --iter)
     701             :   {
     702         710 :     if (nsBufferRoutines<L>::compare(iter, little, littleLen, ignoreCase) == 0)
     703          13 :       return i;
     704             :   }
     705             : 
     706          36 :   return kNotFound;
     707             : }
     708             : 
     709             : template <class CharT, class SetCharT>
     710             : #ifndef __SUNPRO_CC
     711             : static
     712             : #endif /* !__SUNPRO_CC */
     713             : int32_t
     714         336 : FindCharInSet( const CharT* data, uint32_t dataLen, const SetCharT* set )
     715             : {
     716         336 :   CharT filter = nsBufferRoutines<CharT>::get_find_in_set_filter(set);
     717             : 
     718         336 :   const CharT* end = data + dataLen;
     719        6261 :   for (const CharT* iter = data; iter < end; ++iter)
     720             :   {
     721        5931 :     CharT currentChar = *iter;
     722        5931 :     if (currentChar & filter)
     723        4355 :       continue; // char is not in filter set; go on with next char.
     724             : 
     725             :     // test all chars
     726        1576 :     const SetCharT* charInSet = set;
     727        1576 :     CharT setChar = CharT(*charInSet);
     728      118648 :     while (setChar)
     729             :     {
     730       58542 :       if (setChar == currentChar)
     731           6 :         return iter - data; // found it!  return index of the found char.
     732             : 
     733       58536 :       setChar = CharT(*(++charInSet));
     734             :     }
     735             :   }
     736         330 :   return kNotFound;
     737             : }
     738             : 
     739             : template <class CharT, class SetCharT>
     740             : #ifndef __SUNPRO_CC
     741             : static
     742             : #endif /* !__SUNPRO_CC */
     743             : int32_t
     744           0 : RFindCharInSet( const CharT* data, uint32_t dataLen, const SetCharT* set )
     745             : {
     746           0 :   CharT filter = nsBufferRoutines<CharT>::get_find_in_set_filter(set);
     747             : 
     748           0 :   for (const CharT* iter = data + dataLen - 1; iter >= data; --iter)
     749             :   {
     750           0 :     CharT currentChar = *iter;
     751           0 :     if (currentChar & filter)
     752           0 :       continue; // char is not in filter set; go on with next char.
     753             : 
     754             :     // test all chars
     755           0 :     const CharT* charInSet = set;
     756           0 :     CharT setChar = *charInSet;
     757           0 :     while (setChar)
     758             :     {
     759           0 :       if (setChar == currentChar)
     760           0 :         return iter - data; // found it!  return index of the found char.
     761             : 
     762           0 :       setChar = *(++charInSet);
     763             :     }
     764             :   }
     765           0 :   return kNotFound;
     766             : }
     767             : 
     768             : /**
     769             :  * this method changes the meaning of |offset| and |count|:
     770             :  *
     771             :  * upon return,
     772             :  *   |offset| specifies start of search range
     773             :  *   |count| specifies length of search range
     774             :  */
     775             : static void
     776          53 : Find_ComputeSearchRange( uint32_t bigLen, uint32_t littleLen, int32_t& offset, int32_t& count )
     777             : {
     778             :   // |count| specifies how many iterations to make from |offset|
     779             : 
     780          53 :   if (offset < 0)
     781             :   {
     782           0 :     offset = 0;
     783             :   }
     784          53 :   else if (uint32_t(offset) > bigLen)
     785             :   {
     786           0 :     count = 0;
     787           0 :     return;
     788             :   }
     789             : 
     790          53 :   int32_t maxCount = bigLen - offset;
     791          53 :   if (count < 0 || count > maxCount)
     792             :   {
     793          53 :     count = maxCount;
     794             :   }
     795             :   else
     796             :   {
     797           0 :     count += littleLen;
     798           0 :     if (count > maxCount)
     799           0 :       count = maxCount;
     800             :   }
     801             : }
     802             : 
     803             : /**
     804             :  * this method changes the meaning of |offset| and |count|:
     805             :  *
     806             :  * upon entry,
     807             :  *   |offset| specifies the end point from which to search backwards
     808             :  *   |count| specifies the number of iterations from |offset|
     809             :  *
     810             :  * upon return,
     811             :  *   |offset| specifies start of search range
     812             :  *   |count| specifies length of search range
     813             :  *
     814             :  *
     815             :  * EXAMPLE
     816             :  *
     817             :  *                            + -- littleLen=4 -- +
     818             :  *                            :                   :
     819             :  *   |____|____|____|____|____|____|____|____|____|____|____|____|
     820             :  *                            :                                  :
     821             :  *                         offset=5                           bigLen=12
     822             :  *
     823             :  *   if count = 4, then we expect this function to return offset = 2 and
     824             :  *   count = 7.
     825             :  *
     826             :  */
     827             : static void
     828          49 : RFind_ComputeSearchRange( uint32_t bigLen, uint32_t littleLen, int32_t& offset, int32_t& count )
     829             : {
     830          49 :   if (littleLen > bigLen)
     831             :   {
     832           0 :     offset = 0;
     833           0 :     count = 0;
     834           0 :     return;
     835             :   }
     836             : 
     837          49 :   if (offset < 0)
     838          49 :     offset = bigLen - littleLen;
     839          49 :   if (count < 0)
     840          49 :     count = offset + 1;
     841             : 
     842          49 :   int32_t start = offset - count + 1;
     843          49 :   if (start < 0)
     844           0 :     start = 0;
     845             : 
     846          49 :   count = offset + littleLen - start;
     847          49 :   offset = start;
     848             : }
     849             : 
     850             : //-----------------------------------------------------------------------------
     851             : 
     852             : // define nsString obsolete methods
     853             : #include "string-template-def-unichar.h"
     854             : #include "nsTStringObsolete.cpp"
     855             : #include "string-template-undef.h"
     856             : 
     857             : // define nsCString obsolete methods
     858             : #include "string-template-def-char.h"
     859             : #include "nsTStringObsolete.cpp"
     860             : #include "string-template-undef.h"
     861             : 
     862             : //-----------------------------------------------------------------------------
     863             : 
     864             : // specialized methods:
     865             : 
     866             : int32_t
     867          15 : nsString::Find( const nsString& aString, int32_t aOffset, int32_t aCount ) const
     868             : {
     869             :   // this method changes the meaning of aOffset and aCount:
     870          15 :   Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
     871             : 
     872          15 :   int32_t result = FindSubstring(mData + aOffset, aCount, static_cast<const char16_t*>(aString.get()), aString.Length(), false);
     873          15 :   if (result != kNotFound)
     874           7 :     result += aOffset;
     875          15 :   return result;
     876             : }
     877             : 
     878             : int32_t
     879           0 : nsString::Find( const char16_t* aString, int32_t aOffset, int32_t aCount ) const
     880             : {
     881           0 :   return Find(nsDependentString(aString), aOffset, aCount);
     882             : }
     883             : 
     884             : int32_t
     885           0 : nsString::RFind( const nsString& aString, int32_t aOffset, int32_t aCount ) const
     886             : {
     887             :   // this method changes the meaning of aOffset and aCount:
     888           0 :   RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
     889             : 
     890           0 :   int32_t result = RFindSubstring(mData + aOffset, aCount, static_cast<const char16_t*>(aString.get()), aString.Length(), false);
     891           0 :   if (result != kNotFound)
     892           0 :     result += aOffset;
     893           0 :   return result;
     894             : }
     895             : 
     896             : int32_t
     897           0 : nsString::RFind( const char16_t* aString, int32_t aOffset, int32_t aCount ) const
     898             : {
     899           0 :   return RFind(nsDependentString(aString), aOffset, aCount);
     900             : }
     901             : 
     902             : int32_t
     903           0 : nsString::FindCharInSet( const char16_t* aSet, int32_t aOffset ) const
     904             : {
     905           0 :   if (aOffset < 0)
     906           0 :     aOffset = 0;
     907           0 :   else if (aOffset >= int32_t(mLength))
     908           0 :     return kNotFound;
     909             : 
     910           0 :   int32_t result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
     911           0 :   if (result != kNotFound)
     912           0 :     result += aOffset;
     913           0 :   return result;
     914             : }
     915             : 
     916             : void
     917           0 : nsString::ReplaceChar( const char16_t* aSet, char16_t aNewChar )
     918             : {
     919           0 :   if (!EnsureMutable()) // XXX do this lazily?
     920           0 :     AllocFailed(mLength);
     921             : 
     922           0 :   char16_t* data = mData;
     923           0 :   uint32_t lenRemaining = mLength;
     924             : 
     925           0 :   while (lenRemaining)
     926             :   {
     927           0 :     int32_t i = ::FindCharInSet(data, lenRemaining, aSet);
     928           0 :     if (i == kNotFound)
     929           0 :       break;
     930             : 
     931           0 :     data[i++] = aNewChar;
     932           0 :     data += i;
     933           0 :     lenRemaining -= i;
     934             :   }
     935           0 : }
     936             : 
     937             : 
     938             : /**
     939             :  * nsTString::Compare,CompareWithConversion,etc.
     940             :  */
     941             : 
     942             : int32_t
     943        1002 : nsCString::Compare( const char* aString, bool aIgnoreCase, int32_t aCount ) const
     944             : {
     945        1002 :   uint32_t strLen = char_traits::length(aString);
     946             : 
     947        1002 :   int32_t maxCount = int32_t(XPCOM_MIN(mLength, strLen));
     948             : 
     949             :   int32_t compareCount;
     950        1002 :   if (aCount < 0 || aCount > maxCount)
     951         219 :     compareCount = maxCount;
     952             :   else
     953         783 :     compareCount = aCount;
     954             : 
     955             :   int32_t result =
     956        1002 :     nsBufferRoutines<char>::compare(mData, aString, compareCount, aIgnoreCase);
     957             : 
     958        1002 :   if (result == 0 &&
     959         576 :       (aCount < 0 || strLen < uint32_t(aCount) || mLength < uint32_t(aCount)))
     960             :   {
     961             :     // Since the caller didn't give us a length to test, or strings shorter
     962             :     // than aCount, and compareCount characters matched, we have to assume
     963             :     // that the longer string is greater.
     964             : 
     965          10 :     if (mLength != strLen)
     966           3 :       result = (mLength < strLen) ? -1 : 1;
     967             :   }
     968        1002 :   return result;
     969             : }
     970             : 
     971             : bool
     972           0 : nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
     973             : {
     974           0 :   uint32_t strLen = nsCharTraits<char>::length(aString);
     975             : 
     976           0 :   int32_t maxCount = int32_t(XPCOM_MIN(mLength, strLen));
     977             : 
     978             :   int32_t compareCount;
     979           0 :   if (aCount < 0 || aCount > maxCount)
     980           0 :     compareCount = maxCount;
     981             :   else
     982           0 :     compareCount = aCount;
     983             : 
     984             :   int32_t result =
     985           0 :     nsBufferRoutines<char16_t>::compare(mData, aString, compareCount, true);
     986             : 
     987           0 :   if (result == 0 &&
     988           0 :       (aCount < 0 || strLen < uint32_t(aCount) || mLength < uint32_t(aCount)))
     989             :   {
     990             :     // Since the caller didn't give us a length to test, or strings shorter
     991             :     // than aCount, and compareCount characters matched, we have to assume
     992             :     // that the longer string is greater.
     993             : 
     994           0 :     if (mLength != strLen)
     995           0 :       result = 1; // Arbitrarily using any number != 0
     996             :   }
     997           0 :   return result == 0;
     998             : }
     999             : 
    1000             : 
    1001             : /**
    1002             :  * nsTString::ToDouble
    1003             :  */
    1004             : 
    1005             : double
    1006         128 : nsCString::ToDouble(nsresult* aErrorCode) const
    1007             : {
    1008         128 :   double res = 0.0;
    1009         128 :   if (mLength > 0)
    1010             :   {
    1011             :     char *conv_stopped;
    1012         128 :     const char *str = mData;
    1013             :     // Use PR_strtod, not strtod, since we don't want locale involved.
    1014         128 :     res = PR_strtod(str, &conv_stopped);
    1015         128 :     if (conv_stopped == str+mLength)
    1016         128 :       *aErrorCode = NS_OK;
    1017             :     else // Not all the string was scanned
    1018           0 :       *aErrorCode = NS_ERROR_ILLEGAL_VALUE;
    1019             :   }
    1020             :   else
    1021             :   {
    1022             :     // The string was too short (0 characters)
    1023           0 :     *aErrorCode = NS_ERROR_ILLEGAL_VALUE;
    1024             :   }
    1025         128 :   return res;
    1026             : }
    1027             : 
    1028             : double
    1029           0 : nsString::ToDouble(nsresult* aErrorCode) const
    1030             : {
    1031           0 :   return NS_LossyConvertUTF16toASCII(*this).ToDouble(aErrorCode);
    1032             : }
    1033             : 
    1034             : 
    1035             : /**
    1036             :  * nsTString::AssignWithConversion
    1037             :  */
    1038             : 
    1039             : void
    1040           0 : nsCString::AssignWithConversion( const nsAString& aData )
    1041             : {
    1042           0 :   LossyCopyUTF16toASCII(aData, *this);
    1043           0 : }
    1044             : 
    1045             : void
    1046          49 : nsString::AssignWithConversion( const nsACString& aData )
    1047             : {
    1048          49 :   CopyASCIItoUTF16(aData, *this);
    1049          49 : }
    1050             : 
    1051             : #endif // !MOZ_STRING_WITH_OBSOLETE_API

Generated by: LCOV version 1.13