Back to index

lightning-sunbird  0.9+nobinonly
nsTStringObsolete.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim:set ts=2 sw=2 sts=2 et cindent: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla.
00017  *
00018  * The Initial Developer of the Original Code is IBM Corporation.
00019  * Portions created by IBM Corporation are Copyright (C) 2003
00020  * IBM Corporation. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Darin Fisher <darin@meer.net>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00040 
00048 PRInt32
00049 nsTString_CharT::Find( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
00050   {
00051     // this method changes the meaning of aOffset and aCount:
00052     Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
00053 
00054     PRInt32 result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
00055     if (result != kNotFound)
00056       result += aOffset;
00057     return result;
00058   }
00059 
00060 PRInt32
00061 nsTString_CharT::Find( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
00062   {
00063     return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
00064   }
00065 
00066 
00074 PRInt32
00075 nsTString_CharT::RFind( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
00076   {
00077     // this method changes the meaning of aOffset and aCount:
00078     RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
00079 
00080     PRInt32 result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
00081     if (result != kNotFound)
00082       result += aOffset;
00083     return result;
00084   }
00085 
00086 PRInt32
00087 nsTString_CharT::RFind( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
00088   {
00089     return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
00090   }
00091 
00092 
00097 PRInt32
00098 nsTString_CharT::RFindChar( PRUnichar aChar, PRInt32 aOffset, PRInt32 aCount) const
00099   {
00100     return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
00101   }
00102 
00103 
00108 PRInt32
00109 nsTString_CharT::FindCharInSet( const char* aSet, PRInt32 aOffset ) const
00110   {
00111     if (aOffset < 0)
00112       aOffset = 0;
00113     else if (aOffset >= PRInt32(mLength))
00114       return kNotFound;
00115     
00116     PRInt32 result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
00117     if (result != kNotFound)
00118       result += aOffset;
00119     return result;
00120   }
00121 
00122 
00127 PRInt32
00128 nsTString_CharT::RFindCharInSet( const CharT* aSet, PRInt32 aOffset ) const
00129   {
00130     // We want to pass a "data length" to ::RFindCharInSet
00131     if (aOffset < 0 || aOffset > PRInt32(mLength))
00132       aOffset = mLength;
00133     else
00134       ++aOffset;
00135 
00136     return ::RFindCharInSet(mData, aOffset, aSet);
00137   }
00138 
00139 
00140   // it's a shame to replicate this code.  it was done this way in the past
00141   // to help performance.  this function also gets to keep the rickg style
00142   // indentation :-/
00143 PRInt32
00144 nsTString_CharT::ToInteger( PRInt32* aErrorCode, PRUint32 aRadix ) const
00145 {
00146   CharT*  cp=mData;
00147   PRInt32 theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
00148   PRInt32 result=0;
00149   PRBool  negate=PR_FALSE;
00150   CharT   theChar=0;
00151 
00152     //initial value, override if we find an integer
00153   *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
00154   
00155   if(cp) {
00156   
00157     //begin by skipping over leading chars that shouldn't be part of the number...
00158     
00159     CharT*  endcp=cp+mLength;
00160     PRBool  done=PR_FALSE;
00161     
00162     while((cp<endcp) && (!done)){
00163       switch(*cp++) {
00164         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
00165         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00166           theRadix=16;
00167           done=PR_TRUE;
00168           break;
00169         case '0': case '1': case '2': case '3': case '4': 
00170         case '5': case '6': case '7': case '8': case '9':
00171           done=PR_TRUE;
00172           break;
00173         case '-': 
00174           negate=PR_TRUE; //fall through...
00175           break;
00176         case 'X': case 'x': 
00177           theRadix=16;
00178           break; 
00179         default:
00180           break;
00181       } //switch
00182     }
00183 
00184     if (done) {
00185 
00186         //integer found
00187       *aErrorCode = NS_OK;
00188 
00189       if (aRadix!=kAutoDetect) theRadix = aRadix; // override
00190 
00191         //now iterate the numeric chars and build our result
00192       CharT* first=--cp;  //in case we have to back up.
00193       PRBool haveValue = PR_FALSE;
00194 
00195       while(cp<endcp){
00196         theChar=*cp++;
00197         if(('0'<=theChar) && (theChar<='9')){
00198           result = (theRadix * result) + (theChar-'0');
00199           haveValue = PR_TRUE;
00200         }
00201         else if((theChar>='A') && (theChar<='F')) {
00202           if(10==theRadix) {
00203             if(kAutoDetect==aRadix){
00204               theRadix=16;
00205               cp=first; //backup
00206               result=0;
00207               haveValue = PR_FALSE;
00208             }
00209             else {
00210               *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
00211               result=0;
00212               break;
00213             }
00214           }
00215           else {
00216             result = (theRadix * result) + ((theChar-'A')+10);
00217             haveValue = PR_TRUE;
00218           }
00219         }
00220         else if((theChar>='a') && (theChar<='f')) {
00221           if(10==theRadix) {
00222             if(kAutoDetect==aRadix){
00223               theRadix=16;
00224               cp=first; //backup
00225               result=0;
00226               haveValue = PR_FALSE;
00227             }
00228             else {
00229               *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
00230               result=0;
00231               break;
00232             }
00233           }
00234           else {
00235             result = (theRadix * result) + ((theChar-'a')+10);
00236             haveValue = PR_TRUE;
00237           }
00238         }
00239         else if((('X'==theChar) || ('x'==theChar)) && (!haveValue || result == 0)) {
00240           continue;
00241         }
00242         else if((('#'==theChar) || ('+'==theChar)) && !haveValue) {
00243           continue;
00244         }
00245         else {
00246           //we've encountered a char that's not a legal number or sign
00247           break;
00248         }
00249       } //while
00250       if(negate)
00251         result=-result;
00252     } //if
00253   }
00254   return result;
00255 }
00256 
00257 
00262 PRUint32
00263 nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
00264   {
00265     if (aStartPos == 0 && aLengthToCopy >= mLength)
00266       aResult = *this;
00267     else
00268       aResult = Substring(*this, aStartPos, aLengthToCopy);
00269 
00270     return aResult.mLength;
00271   }
00272 
00273 
00278 PRBool
00279 nsTString_CharT::SetCharAt( PRUnichar aChar, PRUint32 aIndex )
00280   {
00281     if (aIndex >= mLength)
00282       return PR_FALSE;
00283 
00284     EnsureMutable();
00285 
00286     mData[aIndex] = CharT(aChar);
00287     return PR_TRUE;
00288   }
00289 
00290  
00295 void
00296 nsTString_CharT::StripChars( const char* aSet )
00297   {
00298     EnsureMutable();
00299     mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
00300   }
00301 
00302 void
00303 nsTString_CharT::StripWhitespace()
00304   {
00305     StripChars(kWhitespace);
00306   }
00307 
00308 
00313 void
00314 nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
00315   {
00316     EnsureMutable(); // XXX do this lazily?
00317 
00318     for (PRUint32 i=0; i<mLength; ++i)
00319       {
00320         if (mData[i] == aOldChar)
00321           mData[i] = aNewChar;
00322       }
00323   }
00324 
00325 void
00326 nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
00327   {
00328     EnsureMutable(); // XXX do this lazily?
00329 
00330     char_type* data = mData;
00331     PRUint32 lenRemaining = mLength;
00332 
00333     while (lenRemaining)
00334       {
00335         PRInt32 i = ::FindCharInSet(data, lenRemaining, aSet);
00336         if (i == kNotFound)
00337           break;
00338 
00339         data[i++] = aNewChar;
00340         data += i;
00341         lenRemaining -= i;
00342       }
00343   }
00344 
00345 void
00346 nsTString_CharT::ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue )
00347   {
00348     ReplaceSubstring(nsTDependentString_CharT(aTarget),
00349                      nsTDependentString_CharT(aNewValue));
00350   }
00351 
00352 void
00353 nsTString_CharT::ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue )
00354   {
00355     if (aTarget.Length() == 0)
00356       return;
00357 
00358     PRUint32 i = 0;
00359     while (i < mLength)
00360       {
00361         PRInt32 r = FindSubstring(mData + i, mLength - i, aTarget.Data(), aTarget.Length(), PR_FALSE);
00362         if (r == kNotFound)
00363           break;
00364 
00365         Replace(i + r, aTarget.Length(), aNewValue);
00366         i += r + aNewValue.Length();
00367       }
00368   }
00369 
00370 
00375 void
00376 nsTString_CharT::Trim( const char* aSet, PRBool aTrimLeading, PRBool aTrimTrailing, PRBool aIgnoreQuotes )
00377   {
00378       // the old implementation worried about aSet being null :-/
00379     if (!aSet)
00380       return;
00381 
00382     char_type* start = mData;
00383     char_type* end   = mData + mLength;
00384 
00385       // skip over quotes if requested
00386     if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
00387           (mData[0] == '\'' || mData[0] == '"'))
00388       {
00389         ++start;
00390         --end;
00391       }
00392 
00393     PRUint32 setLen = nsCharTraits<char>::length(aSet);
00394 
00395     if (aTrimLeading)
00396       {
00397         PRUint32 cutStart = start - mData;
00398         PRUint32 cutLength = 0;
00399 
00400           // walk forward from start to end
00401         for (; start != end; ++start, ++cutLength)
00402           {
00403             PRInt32 pos = FindChar1(aSet, setLen, 0, *start, setLen);
00404             if (pos == kNotFound)
00405               break;
00406           }
00407 
00408         if (cutLength)
00409           {
00410             Cut(cutStart, cutLength);
00411 
00412               // reset iterators
00413             start = mData + cutStart;
00414             end   = mData + mLength - cutStart;
00415           }
00416       }
00417 
00418     if (aTrimTrailing)
00419       {
00420         PRUint32 cutEnd = end - mData;
00421         PRUint32 cutLength = 0;
00422 
00423           // walk backward from end to start
00424         --end;
00425         for (; end >= start; --end, ++cutLength)
00426           {
00427             PRInt32 pos = FindChar1(aSet, setLen, 0, *end, setLen);
00428             if (pos == kNotFound)
00429               break;
00430           }
00431 
00432         if (cutLength)
00433           Cut(cutEnd - cutLength, cutLength);
00434       }
00435   }
00436 
00437 
00442 void
00443 nsTString_CharT::CompressWhitespace( PRBool aTrimLeading, PRBool aTrimTrailing )
00444   {
00445     const char* set = kWhitespace;
00446 
00447     ReplaceChar(set, ' ');
00448     Trim(set, aTrimLeading, aTrimTrailing);
00449 
00450       // this one does some questionable fu... just copying the old code!
00451     mLength = nsBufferRoutines<char_type>::compress_chars(mData, mLength, set);
00452   }
00453 
00454 
00459 void
00460 nsTString_CharT::AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
00461   {
00462       // for compatibility with the old string implementation, we need to allow
00463       // for a NULL input buffer :-(
00464     if (!aData)
00465       {
00466         Truncate();
00467       }
00468     else
00469       {
00470         if (aLength < 0)
00471           aLength = nsCharTraits<incompatible_char_type>::length(aData);
00472 
00473         AssignWithConversion(Substring(aData, aData + aLength));
00474       }
00475   }
00476 
00477 
00482 void
00483 nsTString_CharT::AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
00484   {
00485       // for compatibility with the old string implementation, we need to allow
00486       // for a NULL input buffer :-(
00487     if (aData)
00488       {
00489         if (aLength < 0)
00490           aLength = nsCharTraits<incompatible_char_type>::length(aData);
00491 
00492         AppendWithConversion(Substring(aData, aData + aLength));
00493       }
00494   }