~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/xpcom/string/src/nsTStringObsolete.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
40
 
 
41
  /**
 
42
   * nsTString::Find
 
43
   *
 
44
   * aOffset specifies starting index
 
45
   * aCount specifies number of string compares (iterations)
 
46
   */
 
47
 
 
48
PRInt32
 
49
nsTString_CharT::Find( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
 
50
  {
 
51
    // this method changes the meaning of aOffset and aCount:
 
52
    Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
 
53
 
 
54
    PRInt32 result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
 
55
    if (result != kNotFound)
 
56
      result += aOffset;
 
57
    return result;
 
58
  }
 
59
 
 
60
PRInt32
 
61
nsTString_CharT::Find( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
 
62
  {
 
63
    return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
 
64
  }
 
65
 
 
66
 
 
67
  /**
 
68
   * nsTString::RFind
 
69
   *
 
70
   * aOffset specifies starting index
 
71
   * aCount specifies number of string compares (iterations)
 
72
   */
 
73
 
 
74
PRInt32
 
75
nsTString_CharT::RFind( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
 
76
  {
 
77
    // this method changes the meaning of aOffset and aCount:
 
78
    RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
 
79
 
 
80
    PRInt32 result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
 
81
    if (result != kNotFound)
 
82
      result += aOffset;
 
83
    return result;
 
84
  }
 
85
 
 
86
PRInt32
 
87
nsTString_CharT::RFind( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
 
88
  {
 
89
    return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
 
90
  }
 
91
 
 
92
 
 
93
  /**
 
94
   * nsTString::RFindChar
 
95
   */
 
96
 
 
97
PRInt32
 
98
nsTString_CharT::RFindChar( PRUnichar aChar, PRInt32 aOffset, PRInt32 aCount) const
 
99
  {
 
100
    return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
 
101
  }
 
102
 
 
103
 
 
104
  /**
 
105
   * nsTString::FindCharInSet
 
106
   */
 
107
 
 
108
PRInt32
 
109
nsTString_CharT::FindCharInSet( const char* aSet, PRInt32 aOffset ) const
 
110
  {
 
111
    if (aOffset < 0)
 
112
      aOffset = 0;
 
113
    else if (aOffset >= PRInt32(mLength))
 
114
      return kNotFound;
 
115
    
 
116
    PRInt32 result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
 
117
    if (result != kNotFound)
 
118
      result += aOffset;
 
119
    return result;
 
120
  }
 
121
 
 
122
 
 
123
  /**
 
124
   * nsTString::RFindCharInSet
 
125
   */
 
126
 
 
127
PRInt32
 
128
nsTString_CharT::RFindCharInSet( const CharT* aSet, PRInt32 aOffset ) const
 
129
  {
 
130
    // We want to pass a "data length" to ::RFindCharInSet
 
131
    if (aOffset < 0 || aOffset > PRInt32(mLength))
 
132
      aOffset = mLength;
 
133
    else
 
134
      ++aOffset;
 
135
 
 
136
    return ::RFindCharInSet(mData, aOffset, aSet);
 
137
  }
 
138
 
 
139
 
 
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
 
145
{
 
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;
 
151
 
 
152
    //initial value, override if we find an integer
 
153
  *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
 
154
  
 
155
  if(cp) {
 
156
  
 
157
    //begin by skipping over leading chars that shouldn't be part of the number...
 
158
    
 
159
    CharT*  endcp=cp+mLength;
 
160
    PRBool  done=PR_FALSE;
 
161
    
 
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
 
182
    }
 
183
 
 
184
    if (done) {
 
185
 
 
186
        //integer found
 
187
      *aErrorCode = NS_OK;
 
188
 
 
189
      if (aRadix!=kAutoDetect) theRadix = aRadix; // override
 
190
 
 
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;
 
194
 
 
195
      while(cp<endcp){
 
196
        theChar=*cp++;
 
197
        if(('0'<=theChar) && (theChar<='9')){
 
198
          result = (theRadix * result) + (theChar-'0');
 
199
          haveValue = PR_TRUE;
 
200
        }
 
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;
 
208
            }
 
209
            else {
 
210
              *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
 
211
              result=0;
 
212
              break;
 
213
            }
 
214
          }
 
215
          else {
 
216
            result = (theRadix * result) + ((theChar-'A')+10);
 
217
            haveValue = PR_TRUE;
 
218
          }
 
219
        }
 
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;
 
227
            }
 
228
            else {
 
229
              *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
 
230
              result=0;
 
231
              break;
 
232
            }
 
233
          }
 
234
          else {
 
235
            result = (theRadix * result) + ((theChar-'a')+10);
 
236
            haveValue = PR_TRUE;
 
237
          }
 
238
        }
 
239
        else if((('X'==theChar) || ('x'==theChar)) && (!haveValue || result == 0)) {
 
240
          continue;
 
241
        }
 
242
        else if((('#'==theChar) || ('+'==theChar)) && !haveValue) {
 
243
          continue;
 
244
        }
 
245
        else {
 
246
          //we've encountered a char that's not a legal number or sign
 
247
          break;
 
248
        }
 
249
      } //while
 
250
      if(negate)
 
251
        result=-result;
 
252
    } //if
 
253
  }
 
254
  return result;
 
255
}
 
256
 
 
257
 
 
258
  /**
 
259
   * nsTString::Mid
 
260
   */
 
261
 
 
262
PRUint32
 
263
nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
 
264
  {
 
265
    if (aStartPos == 0 && aLengthToCopy >= mLength)
 
266
      aResult = *this;
 
267
    else
 
268
      aResult = Substring(*this, aStartPos, aLengthToCopy);
 
269
 
 
270
    return aResult.mLength;
 
271
  }
 
272
 
 
273
 
 
274
  /**
 
275
   * nsTString::SetCharAt
 
276
   */
 
277
 
 
278
PRBool
 
279
nsTString_CharT::SetCharAt( PRUnichar aChar, PRUint32 aIndex )
 
280
  {
 
281
    if (aIndex >= mLength)
 
282
      return PR_FALSE;
 
283
 
 
284
    EnsureMutable();
 
285
 
 
286
    mData[aIndex] = CharT(aChar);
 
287
    return PR_TRUE;
 
288
  }
 
289
 
 
290
 
 
291
  /**
 
292
   * nsTString::StripChars,StripChar,StripWhitespace
 
293
   */
 
294
 
 
295
void
 
296
nsTString_CharT::StripChars( const char* aSet )
 
297
  {
 
298
    EnsureMutable();
 
299
    mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
 
300
  }
 
301
 
 
302
void
 
303
nsTString_CharT::StripChar( char_type aChar, PRInt32 aOffset )
 
304
  {
 
305
    if (mLength == 0 || aOffset >= PRInt32(mLength))
 
306
      return;
 
307
 
 
308
    EnsureMutable(); // XXX do this lazily?
 
309
 
 
310
    // XXXdarin this code should defer writing until necessary.
 
311
 
 
312
    char_type* to   = mData + aOffset;
 
313
    char_type* from = mData + aOffset;
 
314
    char_type* end  = mData + mLength;
 
315
 
 
316
    while (from < end)
 
317
      {
 
318
        char_type theChar = *from++;
 
319
        if (aChar != theChar)
 
320
          *to++ = theChar;
 
321
      }
 
322
    *to = char_type(0); // add the null
 
323
    mLength = to - mData;
 
324
  }
 
325
 
 
326
void
 
327
nsTString_CharT::StripWhitespace()
 
328
  {
 
329
    StripChars(kWhitespace);
 
330
  }
 
331
 
 
332
 
 
333
  /**
 
334
   * nsTString::ReplaceChar,ReplaceSubstring
 
335
   */
 
336
 
 
337
void
 
338
nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
 
339
  {
 
340
    EnsureMutable(); // XXX do this lazily?
 
341
 
 
342
    for (PRUint32 i=0; i<mLength; ++i)
 
343
      {
 
344
        if (mData[i] == aOldChar)
 
345
          mData[i] = aNewChar;
 
346
      }
 
347
  }
 
348
 
 
349
void
 
350
nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
 
351
  {
 
352
    EnsureMutable(); // XXX do this lazily?
 
353
 
 
354
    char_type* data = mData;
 
355
    PRUint32 lenRemaining = mLength;
 
356
 
 
357
    while (lenRemaining)
 
358
      {
 
359
        PRInt32 i = ::FindCharInSet(data, lenRemaining, aSet);
 
360
        if (i == kNotFound)
 
361
          break;
 
362
 
 
363
        data[i++] = aNewChar;
 
364
        data += i;
 
365
        lenRemaining -= i;
 
366
      }
 
367
  }
 
368
 
 
369
void
 
370
nsTString_CharT::ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue )
 
371
  {
 
372
    ReplaceSubstring(nsTDependentString_CharT(aTarget),
 
373
                     nsTDependentString_CharT(aNewValue));
 
374
  }
 
375
 
 
376
void
 
377
nsTString_CharT::ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue )
 
378
  {
 
379
    if (aTarget.Length() == 0)
 
380
      return;
 
381
 
 
382
    PRUint32 i = 0;
 
383
    while (i < mLength)
 
384
      {
 
385
        PRInt32 r = FindSubstring(mData + i, mLength - i, aTarget.Data(), aTarget.Length(), PR_FALSE);
 
386
        if (r == kNotFound)
 
387
          break;
 
388
 
 
389
        Replace(i + r, aTarget.Length(), aNewValue);
 
390
        i += r + aNewValue.Length();
 
391
      }
 
392
  }
 
393
 
 
394
 
 
395
  /**
 
396
   * nsTString::Trim
 
397
   */
 
398
 
 
399
void
 
400
nsTString_CharT::Trim( const char* aSet, PRBool aTrimLeading, PRBool aTrimTrailing, PRBool aIgnoreQuotes )
 
401
  {
 
402
      // the old implementation worried about aSet being null :-/
 
403
    if (!aSet)
 
404
      return;
 
405
 
 
406
    char_type* start = mData;
 
407
    char_type* end   = mData + mLength;
 
408
 
 
409
      // skip over quotes if requested
 
410
    if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
 
411
          (mData[0] == '\'' || mData[0] == '"'))
 
412
      {
 
413
        ++start;
 
414
        --end;
 
415
      }
 
416
 
 
417
    PRUint32 setLen = nsCharTraits<char>::length(aSet);
 
418
 
 
419
    if (aTrimLeading)
 
420
      {
 
421
        PRUint32 cutStart = start - mData;
 
422
        PRUint32 cutLength = 0;
 
423
 
 
424
          // walk forward from start to end
 
425
        for (; start != end; ++start, ++cutLength)
 
426
          {
 
427
            PRInt32 pos = FindChar1(aSet, setLen, 0, *start, setLen);
 
428
            if (pos == kNotFound)
 
429
              break;
 
430
          }
 
431
 
 
432
        if (cutLength)
 
433
          {
 
434
            Cut(cutStart, cutLength);
 
435
 
 
436
              // reset iterators
 
437
            start = mData + cutStart;
 
438
            end   = mData + mLength - cutStart;
 
439
          }
 
440
      }
 
441
 
 
442
    if (aTrimTrailing)
 
443
      {
 
444
        PRUint32 cutEnd = end - mData;
 
445
        PRUint32 cutLength = 0;
 
446
 
 
447
          // walk backward from end to start
 
448
        --end;
 
449
        for (; end >= start; --end, ++cutLength)
 
450
          {
 
451
            PRInt32 pos = FindChar1(aSet, setLen, 0, *end, setLen);
 
452
            if (pos == kNotFound)
 
453
              break;
 
454
          }
 
455
 
 
456
        if (cutLength)
 
457
          Cut(cutEnd - cutLength, cutLength);
 
458
      }
 
459
  }
 
460
 
 
461
 
 
462
  /**
 
463
   * nsTString::CompressWhitespace
 
464
   */
 
465
 
 
466
void
 
467
nsTString_CharT::CompressWhitespace( PRBool aTrimLeading, PRBool aTrimTrailing )
 
468
  {
 
469
    const char* set = kWhitespace;
 
470
 
 
471
    ReplaceChar(set, ' ');
 
472
    Trim(set, aTrimLeading, aTrimTrailing);
 
473
 
 
474
      // this one does some questionable fu... just copying the old code!
 
475
    mLength = nsBufferRoutines<char_type>::compress_chars(mData, mLength, set);
 
476
  }
 
477
 
 
478
 
 
479
  /**
 
480
   * nsTString::AssignWithConversion
 
481
   */
 
482
 
 
483
void
 
484
nsTString_CharT::AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
 
485
  {
 
486
      // for compatibility with the old string implementation, we need to allow
 
487
      // for a NULL input buffer :-(
 
488
    if (!aData)
 
489
      {
 
490
        Truncate();
 
491
      }
 
492
    else
 
493
      {
 
494
        if (aLength < 0)
 
495
          aLength = nsCharTraits<incompatible_char_type>::length(aData);
 
496
 
 
497
        AssignWithConversion(Substring(aData, aData + aLength));
 
498
      }
 
499
  }
 
500
 
 
501
 
 
502
  /**
 
503
   * nsTString::AppendWithConversion
 
504
   */
 
505
 
 
506
void
 
507
nsTString_CharT::AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
 
508
  {
 
509
      // for compatibility with the old string implementation, we need to allow
 
510
      // for a NULL input buffer :-(
 
511
    if (aData)
 
512
      {
 
513
        if (aLength < 0)
 
514
          aLength = nsCharTraits<incompatible_char_type>::length(aData);
 
515
 
 
516
        AppendWithConversion(Substring(aData, aData + aLength));
 
517
      }
 
518
  }