xpcom/string/src/nsTStringObsolete.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 /* 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/. */
     9   /**
    10    * nsTString::Find
    11    *
    12    * aOffset specifies starting index
    13    * aCount specifies number of string compares (iterations)
    14    */
    16 int32_t
    17 nsTString_CharT::Find( const nsCString& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
    18   {
    19     // this method changes the meaning of aOffset and aCount:
    20     Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
    22     int32_t result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
    23     if (result != kNotFound)
    24       result += aOffset;
    25     return result;
    26   }
    28 int32_t
    29 nsTString_CharT::Find( const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
    30   {
    31     return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
    32   }
    35   /**
    36    * nsTString::RFind
    37    *
    38    * aOffset specifies starting index
    39    * aCount specifies number of string compares (iterations)
    40    */
    42 int32_t
    43 nsTString_CharT::RFind( const nsCString& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
    44   {
    45     // this method changes the meaning of aOffset and aCount:
    46     RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
    48     int32_t result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
    49     if (result != kNotFound)
    50       result += aOffset;
    51     return result;
    52   }
    54 int32_t
    55 nsTString_CharT::RFind( const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
    56   {
    57     return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
    58   }
    61   /**
    62    * nsTString::RFindChar
    63    */
    65 int32_t
    66 nsTString_CharT::RFindChar( char16_t aChar, int32_t aOffset, int32_t aCount) const
    67   {
    68     return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
    69   }
    72   /**
    73    * nsTString::FindCharInSet
    74    */
    76 int32_t
    77 nsTString_CharT::FindCharInSet( const char* aSet, int32_t aOffset ) const
    78   {
    79     if (aOffset < 0)
    80       aOffset = 0;
    81     else if (aOffset >= int32_t(mLength))
    82       return kNotFound;
    84     int32_t result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
    85     if (result != kNotFound)
    86       result += aOffset;
    87     return result;
    88   }
    91   /**
    92    * nsTString::RFindCharInSet
    93    */
    95 int32_t
    96 nsTString_CharT::RFindCharInSet( const CharT* aSet, int32_t aOffset ) const
    97   {
    98     // We want to pass a "data length" to ::RFindCharInSet
    99     if (aOffset < 0 || aOffset > int32_t(mLength))
   100       aOffset = mLength;
   101     else
   102       ++aOffset;
   104     return ::RFindCharInSet(mData, aOffset, aSet);
   105   }
   108   // it's a shame to replicate this code.  it was done this way in the past
   109   // to help performance.  this function also gets to keep the rickg style
   110   // indentation :-/
   111 int32_t
   112 nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
   113 {
   114   CharT*  cp=mData;
   115   int32_t theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
   116   int32_t result=0;
   117   bool    negate=false;
   118   CharT   theChar=0;
   120     //initial value, override if we find an integer
   121   *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
   123   if(cp) {
   125     //begin by skipping over leading chars that shouldn't be part of the number...
   127     CharT*  endcp=cp+mLength;
   128     bool    done=false;
   130     while((cp<endcp) && (!done)){
   131       switch(*cp++) {
   132         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
   133         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
   134           theRadix=16;
   135           done=true;
   136           break;
   137         case '0': case '1': case '2': case '3': case '4': 
   138         case '5': case '6': case '7': case '8': case '9':
   139           done=true;
   140           break;
   141         case '-': 
   142           negate=true; //fall through...
   143           break;
   144         case 'X': case 'x': 
   145           theRadix=16;
   146           break; 
   147         default:
   148           break;
   149       } //switch
   150     }
   152     if (done) {
   154         //integer found
   155       *aErrorCode = NS_OK;
   157       if (aRadix!=kAutoDetect) theRadix = aRadix; // override
   159         //now iterate the numeric chars and build our result
   160       CharT* first=--cp;  //in case we have to back up.
   161       bool haveValue = false;
   163       while(cp<endcp){
   164         int32_t oldresult = result;
   166         theChar=*cp++;
   167         if(('0'<=theChar) && (theChar<='9')){
   168           result = (theRadix * result) + (theChar-'0');
   169           haveValue = true;
   170         }
   171         else if((theChar>='A') && (theChar<='F')) {
   172           if(10==theRadix) {
   173             if(kAutoDetect==aRadix){
   174               theRadix=16;
   175               cp=first; //backup
   176               result=0;
   177               haveValue = false;
   178             }
   179             else {
   180               *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
   181               result=0;
   182               break;
   183             }
   184           }
   185           else {
   186             result = (theRadix * result) + ((theChar-'A')+10);
   187             haveValue = true;
   188           }
   189         }
   190         else if((theChar>='a') && (theChar<='f')) {
   191           if(10==theRadix) {
   192             if(kAutoDetect==aRadix){
   193               theRadix=16;
   194               cp=first; //backup
   195               result=0;
   196               haveValue = false;
   197             }
   198             else {
   199               *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
   200               result=0;
   201               break;
   202             }
   203           }
   204           else {
   205             result = (theRadix * result) + ((theChar-'a')+10);
   206             haveValue = true;
   207           }
   208         }
   209         else if((('X'==theChar) || ('x'==theChar)) && (!haveValue || result == 0)) {
   210           continue;
   211         }
   212         else if((('#'==theChar) || ('+'==theChar)) && !haveValue) {
   213           continue;
   214         }
   215         else {
   216           //we've encountered a char that's not a legal number or sign
   217           break;
   218         }
   220         if (result < oldresult) {
   221           // overflow!
   222           *aErrorCode = NS_ERROR_ILLEGAL_VALUE;
   223           result = 0;
   224           break;
   225         }
   226       } //while
   227       if(negate)
   228         result=-result;
   229     } //if
   230   }
   231   return result;
   232 }
   235   /**
   236    * nsTString::ToInteger64
   237    */
   238 int64_t
   239 nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
   240 {
   241   CharT*  cp=mData;
   242   int32_t theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
   243   int64_t result=0;
   244   bool    negate=false;
   245   CharT   theChar=0;
   247     //initial value, override if we find an integer
   248   *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
   250   if(cp) {
   252     //begin by skipping over leading chars that shouldn't be part of the number...
   254     CharT*  endcp=cp+mLength;
   255     bool    done=false;
   257     while((cp<endcp) && (!done)){
   258       switch(*cp++) {
   259         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
   260         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
   261           theRadix=16;
   262           done=true;
   263           break;
   264         case '0': case '1': case '2': case '3': case '4':
   265         case '5': case '6': case '7': case '8': case '9':
   266           done=true;
   267           break;
   268         case '-':
   269           negate=true; //fall through...
   270           break;
   271         case 'X': case 'x':
   272           theRadix=16;
   273           break;
   274         default:
   275           break;
   276       } //switch
   277     }
   279     if (done) {
   281         //integer found
   282       *aErrorCode = NS_OK;
   284       if (aRadix!=kAutoDetect) theRadix = aRadix; // override
   286         //now iterate the numeric chars and build our result
   287       CharT* first=--cp;  //in case we have to back up.
   288       bool haveValue = false;
   290       while(cp<endcp){
   291         int64_t oldresult = result;
   293         theChar=*cp++;
   294         if(('0'<=theChar) && (theChar<='9')){
   295           result = (theRadix * result) + (theChar-'0');
   296           haveValue = true;
   297         }
   298         else if((theChar>='A') && (theChar<='F')) {
   299           if(10==theRadix) {
   300             if(kAutoDetect==aRadix){
   301               theRadix=16;
   302               cp=first; //backup
   303               result=0;
   304               haveValue = false;
   305             }
   306             else {
   307               *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
   308               result=0;
   309               break;
   310             }
   311           }
   312           else {
   313             result = (theRadix * result) + ((theChar-'A')+10);
   314             haveValue = true;
   315           }
   316         }
   317         else if((theChar>='a') && (theChar<='f')) {
   318           if(10==theRadix) {
   319             if(kAutoDetect==aRadix){
   320               theRadix=16;
   321               cp=first; //backup
   322               result=0;
   323               haveValue = false;
   324             }
   325             else {
   326               *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
   327               result=0;
   328               break;
   329             }
   330           }
   331           else {
   332             result = (theRadix * result) + ((theChar-'a')+10);
   333             haveValue = true;
   334           }
   335         }
   336         else if((('X'==theChar) || ('x'==theChar)) && (!haveValue || result == 0)) {
   337           continue;
   338         }
   339         else if((('#'==theChar) || ('+'==theChar)) && !haveValue) {
   340           continue;
   341         }
   342         else {
   343           //we've encountered a char that's not a legal number or sign
   344           break;
   345         }
   347         if (result < oldresult) {
   348           // overflow!
   349           *aErrorCode = NS_ERROR_ILLEGAL_VALUE;
   350           result = 0;
   351           break;
   352         }
   353       } //while
   354       if(negate)
   355         result=-result;
   356     } //if
   357   }
   358   return result;
   359 }
   362 /**
   363    * nsTString::Mid
   364    */
   366 uint32_t
   367 nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
   368   {
   369     if (aStartPos == 0 && aLengthToCopy >= mLength)
   370       aResult = *this;
   371     else
   372       aResult = Substring(*this, aStartPos, aLengthToCopy);
   374     return aResult.mLength;
   375   }
   378   /**
   379    * nsTString::SetCharAt
   380    */
   382 bool
   383 nsTString_CharT::SetCharAt( char16_t aChar, uint32_t aIndex )
   384   {
   385     if (aIndex >= mLength)
   386       return false;
   388     if (!EnsureMutable())
   389       NS_ABORT_OOM(mLength);
   391     mData[aIndex] = CharT(aChar);
   392     return true;
   393   }
   396   /**
   397    * nsTString::StripChars,StripChar,StripWhitespace
   398    */
   400 void
   401 nsTString_CharT::StripChars( const char* aSet )
   402   {
   403     if (!EnsureMutable())
   404       NS_ABORT_OOM(mLength);
   406     mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
   407   }
   409 void
   410 nsTString_CharT::StripWhitespace()
   411   {
   412     StripChars(kWhitespace);
   413   }
   416   /**
   417    * nsTString::ReplaceChar,ReplaceSubstring
   418    */
   420 void
   421 nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
   422   {
   423     if (!EnsureMutable()) // XXX do this lazily?
   424       NS_ABORT_OOM(mLength);
   426     for (uint32_t i=0; i<mLength; ++i)
   427       {
   428         if (mData[i] == aOldChar)
   429           mData[i] = aNewChar;
   430       }
   431   }
   433 void
   434 nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
   435   {
   436     if (!EnsureMutable()) // XXX do this lazily?
   437       NS_ABORT_OOM(mLength);
   439     char_type* data = mData;
   440     uint32_t lenRemaining = mLength;
   442     while (lenRemaining)
   443       {
   444         int32_t i = ::FindCharInSet(data, lenRemaining, aSet);
   445         if (i == kNotFound)
   446           break;
   448         data[i++] = aNewChar;
   449         data += i;
   450         lenRemaining -= i;
   451       }
   452   }
   454 void
   455 nsTString_CharT::ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue )
   456   {
   457     ReplaceSubstring(nsTDependentString_CharT(aTarget),
   458                      nsTDependentString_CharT(aNewValue));
   459   }
   461 void
   462 nsTString_CharT::ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue )
   463   {
   464     if (aTarget.Length() == 0)
   465       return;
   467     uint32_t i = 0;
   468     while (i < mLength)
   469       {
   470         int32_t r = FindSubstring(mData + i, mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
   471         if (r == kNotFound)
   472           break;
   474         Replace(i + r, aTarget.Length(), aNewValue);
   475         i += r + aNewValue.Length();
   476       }
   477   }
   480   /**
   481    * nsTString::Trim
   482    */
   484 void
   485 nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing, bool aIgnoreQuotes )
   486   {
   487       // the old implementation worried about aSet being null :-/
   488     if (!aSet)
   489       return;
   491     char_type* start = mData;
   492     char_type* end   = mData + mLength;
   494       // skip over quotes if requested
   495     if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
   496           (mData[0] == '\'' || mData[0] == '"'))
   497       {
   498         ++start;
   499         --end;
   500       }
   502     uint32_t setLen = nsCharTraits<char>::length(aSet);
   504     if (aTrimLeading)
   505       {
   506         uint32_t cutStart = start - mData;
   507         uint32_t cutLength = 0;
   509           // walk forward from start to end
   510         for (; start != end; ++start, ++cutLength)
   511           {
   512             int32_t pos = FindChar1(aSet, setLen, 0, *start, setLen);
   513             if (pos == kNotFound)
   514               break;
   515           }
   517         if (cutLength)
   518           {
   519             Cut(cutStart, cutLength);
   521               // reset iterators
   522             start = mData + cutStart;
   523             end   = mData + mLength - cutStart;
   524           }
   525       }
   527     if (aTrimTrailing)
   528       {
   529         uint32_t cutEnd = end - mData;
   530         uint32_t cutLength = 0;
   532           // walk backward from end to start
   533         --end;
   534         for (; end >= start; --end, ++cutLength)
   535           {
   536             int32_t pos = FindChar1(aSet, setLen, 0, *end, setLen);
   537             if (pos == kNotFound)
   538               break;
   539           }
   541         if (cutLength)
   542           Cut(cutEnd - cutLength, cutLength);
   543       }
   544   }
   547   /**
   548    * nsTString::CompressWhitespace
   549    */
   551 void
   552 nsTString_CharT::CompressWhitespace( bool aTrimLeading, bool aTrimTrailing )
   553   {
   554     const char* set = kWhitespace;
   556     ReplaceChar(set, ' ');
   557     Trim(set, aTrimLeading, aTrimTrailing);
   559       // this one does some questionable fu... just copying the old code!
   560     mLength = nsBufferRoutines<char_type>::compress_chars(mData, mLength, set);
   561   }
   564   /**
   565    * nsTString::AssignWithConversion
   566    */
   568 void
   569 nsTString_CharT::AssignWithConversion( const incompatible_char_type* aData, int32_t aLength )
   570   {
   571       // for compatibility with the old string implementation, we need to allow
   572       // for a nullptr input buffer :-(
   573     if (!aData)
   574       {
   575         Truncate();
   576       }
   577     else
   578       {
   579         if (aLength < 0)
   580           aLength = nsCharTraits<incompatible_char_type>::length(aData);
   582         AssignWithConversion(Substring(aData, aLength));
   583       }
   584   }

mercurial