Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / xpcom / string / src / nsTStringObsolete.cpp
blobc1425a6ba07f3b522221fb4f2c9e22d81b3dd169
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
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/
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.
16 * The Original Code is Mozilla.
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.
22 * Contributor(s):
23 * Darin Fisher <darin@meer.net>
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.
37 * ***** END LICENSE BLOCK ***** */
41 /**
42 * nsTString::Find
44 * aOffset specifies starting index
45 * aCount specifies number of string compares (iterations)
48 PRInt32
49 nsTString_CharT::Find( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
51 // this method changes the meaning of aOffset and aCount:
52 Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
54 PRInt32 result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
55 if (result != kNotFound)
56 result += aOffset;
57 return result;
60 PRInt32
61 nsTString_CharT::Find( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
63 return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
67 /**
68 * nsTString::RFind
70 * aOffset specifies starting index
71 * aCount specifies number of string compares (iterations)
74 PRInt32
75 nsTString_CharT::RFind( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
77 // this method changes the meaning of aOffset and aCount:
78 RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
80 PRInt32 result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
81 if (result != kNotFound)
82 result += aOffset;
83 return result;
86 PRInt32
87 nsTString_CharT::RFind( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
89 return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
93 /**
94 * nsTString::RFindChar
97 PRInt32
98 nsTString_CharT::RFindChar( PRUnichar aChar, PRInt32 aOffset, PRInt32 aCount) const
100 return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
105 * nsTString::FindCharInSet
108 PRInt32
109 nsTString_CharT::FindCharInSet( const char* aSet, PRInt32 aOffset ) const
111 if (aOffset < 0)
112 aOffset = 0;
113 else if (aOffset >= PRInt32(mLength))
114 return kNotFound;
116 PRInt32 result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
117 if (result != kNotFound)
118 result += aOffset;
119 return result;
124 * nsTString::RFindCharInSet
127 PRInt32
128 nsTString_CharT::RFindCharInSet( const CharT* aSet, PRInt32 aOffset ) const
130 // We want to pass a "data length" to ::RFindCharInSet
131 if (aOffset < 0 || aOffset > PRInt32(mLength))
132 aOffset = mLength;
133 else
134 ++aOffset;
136 return ::RFindCharInSet(mData, aOffset, aSet);
140 // it's a shame to replicate this code. it was done this way in the past
141 // to help performance. this function also gets to keep the rickg style
142 // indentation :-/
143 PRInt32
144 nsTString_CharT::ToInteger( PRInt32* aErrorCode, PRUint32 aRadix ) const
146 CharT* cp=mData;
147 PRInt32 theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
148 PRInt32 result=0;
149 PRBool negate=PR_FALSE;
150 CharT theChar=0;
152 //initial value, override if we find an integer
153 *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
155 if(cp) {
157 //begin by skipping over leading chars that shouldn't be part of the number...
159 CharT* endcp=cp+mLength;
160 PRBool done=PR_FALSE;
162 while((cp<endcp) && (!done)){
163 switch(*cp++) {
164 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
165 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
166 theRadix=16;
167 done=PR_TRUE;
168 break;
169 case '0': case '1': case '2': case '3': case '4':
170 case '5': case '6': case '7': case '8': case '9':
171 done=PR_TRUE;
172 break;
173 case '-':
174 negate=PR_TRUE; //fall through...
175 break;
176 case 'X': case 'x':
177 theRadix=16;
178 break;
179 default:
180 break;
181 } //switch
184 if (done) {
186 //integer found
187 *aErrorCode = NS_OK;
189 if (aRadix!=kAutoDetect) theRadix = aRadix; // override
191 //now iterate the numeric chars and build our result
192 CharT* first=--cp; //in case we have to back up.
193 PRBool haveValue = PR_FALSE;
195 while(cp<endcp){
196 theChar=*cp++;
197 if(('0'<=theChar) && (theChar<='9')){
198 result = (theRadix * result) + (theChar-'0');
199 haveValue = PR_TRUE;
201 else if((theChar>='A') && (theChar<='F')) {
202 if(10==theRadix) {
203 if(kAutoDetect==aRadix){
204 theRadix=16;
205 cp=first; //backup
206 result=0;
207 haveValue = PR_FALSE;
209 else {
210 *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
211 result=0;
212 break;
215 else {
216 result = (theRadix * result) + ((theChar-'A')+10);
217 haveValue = PR_TRUE;
220 else if((theChar>='a') && (theChar<='f')) {
221 if(10==theRadix) {
222 if(kAutoDetect==aRadix){
223 theRadix=16;
224 cp=first; //backup
225 result=0;
226 haveValue = PR_FALSE;
228 else {
229 *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
230 result=0;
231 break;
234 else {
235 result = (theRadix * result) + ((theChar-'a')+10);
236 haveValue = PR_TRUE;
239 else if((('X'==theChar) || ('x'==theChar)) && (!haveValue || result == 0)) {
240 continue;
242 else if((('#'==theChar) || ('+'==theChar)) && !haveValue) {
243 continue;
245 else {
246 //we've encountered a char that's not a legal number or sign
247 break;
249 } //while
250 if(negate)
251 result=-result;
252 } //if
254 return result;
259 * nsTString::Mid
262 PRUint32
263 nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
265 if (aStartPos == 0 && aLengthToCopy >= mLength)
266 aResult = *this;
267 else
268 aResult = Substring(*this, aStartPos, aLengthToCopy);
270 return aResult.mLength;
275 * nsTString::SetCharAt
278 PRBool
279 nsTString_CharT::SetCharAt( PRUnichar aChar, PRUint32 aIndex )
281 if (aIndex >= mLength)
282 return PR_FALSE;
284 EnsureMutable();
286 mData[aIndex] = CharT(aChar);
287 return PR_TRUE;
292 * nsTString::StripChars,StripChar,StripWhitespace
295 void
296 nsTString_CharT::StripChars( const char* aSet )
298 EnsureMutable();
299 mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
302 void
303 nsTString_CharT::StripWhitespace()
305 StripChars(kWhitespace);
310 * nsTString::ReplaceChar,ReplaceSubstring
313 void
314 nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
316 EnsureMutable(); // XXX do this lazily?
318 for (PRUint32 i=0; i<mLength; ++i)
320 if (mData[i] == aOldChar)
321 mData[i] = aNewChar;
325 void
326 nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
328 EnsureMutable(); // XXX do this lazily?
330 char_type* data = mData;
331 PRUint32 lenRemaining = mLength;
333 while (lenRemaining)
335 PRInt32 i = ::FindCharInSet(data, lenRemaining, aSet);
336 if (i == kNotFound)
337 break;
339 data[i++] = aNewChar;
340 data += i;
341 lenRemaining -= i;
345 void
346 nsTString_CharT::ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue )
348 ReplaceSubstring(nsTDependentString_CharT(aTarget),
349 nsTDependentString_CharT(aNewValue));
352 void
353 nsTString_CharT::ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue )
355 if (aTarget.Length() == 0)
356 return;
358 PRUint32 i = 0;
359 while (i < mLength)
361 PRInt32 r = FindSubstring(mData + i, mLength - i, aTarget.Data(), aTarget.Length(), PR_FALSE);
362 if (r == kNotFound)
363 break;
365 Replace(i + r, aTarget.Length(), aNewValue);
366 i += r + aNewValue.Length();
372 * nsTString::Trim
375 void
376 nsTString_CharT::Trim( const char* aSet, PRBool aTrimLeading, PRBool aTrimTrailing, PRBool aIgnoreQuotes )
378 // the old implementation worried about aSet being null :-/
379 if (!aSet)
380 return;
382 char_type* start = mData;
383 char_type* end = mData + mLength;
385 // skip over quotes if requested
386 if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
387 (mData[0] == '\'' || mData[0] == '"'))
389 ++start;
390 --end;
393 PRUint32 setLen = nsCharTraits<char>::length(aSet);
395 if (aTrimLeading)
397 PRUint32 cutStart = start - mData;
398 PRUint32 cutLength = 0;
400 // walk forward from start to end
401 for (; start != end; ++start, ++cutLength)
403 PRInt32 pos = FindChar1(aSet, setLen, 0, *start, setLen);
404 if (pos == kNotFound)
405 break;
408 if (cutLength)
410 Cut(cutStart, cutLength);
412 // reset iterators
413 start = mData + cutStart;
414 end = mData + mLength - cutStart;
418 if (aTrimTrailing)
420 PRUint32 cutEnd = end - mData;
421 PRUint32 cutLength = 0;
423 // walk backward from end to start
424 --end;
425 for (; end >= start; --end, ++cutLength)
427 PRInt32 pos = FindChar1(aSet, setLen, 0, *end, setLen);
428 if (pos == kNotFound)
429 break;
432 if (cutLength)
433 Cut(cutEnd - cutLength, cutLength);
439 * nsTString::CompressWhitespace
442 void
443 nsTString_CharT::CompressWhitespace( PRBool aTrimLeading, PRBool aTrimTrailing )
445 const char* set = kWhitespace;
447 ReplaceChar(set, ' ');
448 Trim(set, aTrimLeading, aTrimTrailing);
450 // this one does some questionable fu... just copying the old code!
451 mLength = nsBufferRoutines<char_type>::compress_chars(mData, mLength, set);
456 * nsTString::AssignWithConversion
459 void
460 nsTString_CharT::AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
462 // for compatibility with the old string implementation, we need to allow
463 // for a NULL input buffer :-(
464 if (!aData)
466 Truncate();
468 else
470 if (aLength < 0)
471 aLength = nsCharTraits<incompatible_char_type>::length(aData);
473 AssignWithConversion(Substring(aData, aData + aLength));
479 * nsTString::AppendWithConversion
482 void
483 nsTString_CharT::AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
485 // for compatibility with the old string implementation, we need to allow
486 // for a NULL input buffer :-(
487 if (aData)
489 if (aLength < 0)
490 aLength = nsCharTraits<incompatible_char_type>::length(aData);
492 AppendWithConversion(Substring(aData, aData + aLength));