LCOV - code coverage report
Current view: directory - xpcom/string/src - nsStringObsolete.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 342 209 61.1 %
Date: 2012-06-02 Functions: 52 33 63.5 %

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

Generated by: LCOV version 1.7