Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/string/nsTStringObsolete.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
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/. */
6
7
#include "nsTArray.h"
8
#include "nsASCIIMask.h"
9
#include "mozilla/CheckedInt.h"
10
11
/**
12
 * nsTString::Find
13
 *
14
 * aOffset specifies starting index
15
 * aCount specifies number of string compares (iterations)
16
 */
17
template <typename T>
18
int32_t
19
nsTString<T>::Find(const nsTString<char>& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
20
6.04k
{
21
6.04k
  // this method changes the meaning of aOffset and aCount:
22
6.04k
  Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
23
6.04k
24
6.04k
  int32_t result = FindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
25
6.04k
  if (result != kNotFound)
26
6.04k
    result += aOffset;
27
6.04k
  return result;
28
6.04k
}
nsTString<char>::Find(nsTString<char> const&, bool, int, int) const
Line
Count
Source
20
6.04k
{
21
6.04k
  // this method changes the meaning of aOffset and aCount:
22
6.04k
  Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
23
6.04k
24
6.04k
  int32_t result = FindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
25
6.04k
  if (result != kNotFound)
26
6.04k
    result += aOffset;
27
6.04k
  return result;
28
6.04k
}
Unexecuted instantiation: nsTString<char16_t>::Find(nsTString<char> const&, bool, int, int) const
29
30
template <typename T>
31
int32_t
32
nsTString<T>::Find(const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
33
875
{
34
875
  return Find(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
35
875
}
nsTString<char>::Find(char const*, bool, int, int) const
Line
Count
Source
33
875
{
34
875
  return Find(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
35
875
}
Unexecuted instantiation: nsTString<char16_t>::Find(char const*, bool, int, int) const
36
37
38
/**
39
 * nsTString::RFind
40
 *
41
 * aOffset specifies starting index
42
 * aCount specifies number of string compares (iterations)
43
 */
44
template <typename T>
45
int32_t
46
nsTString<T>::RFind(const nsTString<char>& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
47
0
{
48
0
  // this method changes the meaning of aOffset and aCount:
49
0
  RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
50
0
51
0
  int32_t result = RFindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
52
0
  if (result != kNotFound)
53
0
    result += aOffset;
54
0
  return result;
55
0
}
Unexecuted instantiation: nsTString<char>::RFind(nsTString<char> const&, bool, int, int) const
Unexecuted instantiation: nsTString<char16_t>::RFind(nsTString<char> const&, bool, int, int) const
56
57
template <typename T>
58
int32_t
59
nsTString<T>::RFind(const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
60
0
{
61
0
  return RFind(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
62
0
}
Unexecuted instantiation: nsTString<char>::RFind(char const*, bool, int, int) const
Unexecuted instantiation: nsTString<char16_t>::RFind(char const*, bool, int, int) const
63
64
65
/**
66
 * nsTString::RFindChar
67
 */
68
template <typename T>
69
int32_t
70
nsTString<T>::RFindChar(char16_t aChar, int32_t aOffset, int32_t aCount) const
71
337
{
72
337
  return nsBufferRoutines<T>::rfind_char(this->mData, this->mLength, aOffset, aChar, aCount);
73
337
}
nsTString<char>::RFindChar(char16_t, int, int) const
Line
Count
Source
71
337
{
72
337
  return nsBufferRoutines<T>::rfind_char(this->mData, this->mLength, aOffset, aChar, aCount);
73
337
}
Unexecuted instantiation: nsTString<char16_t>::RFindChar(char16_t, int, int) const
74
75
76
/**
77
 * nsTString::FindCharInSet
78
 */
79
80
template <typename T>
81
int32_t
82
nsTString<T>::FindCharInSet(const char_type* aSet, int32_t aOffset) const
83
34.0k
{
84
34.0k
  if (aOffset < 0)
85
0
    aOffset = 0;
86
34.0k
  else if (aOffset >= int32_t(this->mLength))
87
699
    return kNotFound;
88
33.3k
89
33.3k
  int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
90
33.3k
  if (result != kNotFound)
91
33.3k
    result += aOffset;
92
33.3k
  return result;
93
33.3k
}
nsTString<char>::FindCharInSet(char const*, int) const
Line
Count
Source
83
7.26k
{
84
7.26k
  if (aOffset < 0)
85
0
    aOffset = 0;
86
7.26k
  else if (aOffset >= int32_t(this->mLength))
87
699
    return kNotFound;
88
6.56k
89
6.56k
  int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
90
6.56k
  if (result != kNotFound)
91
6.56k
    result += aOffset;
92
6.56k
  return result;
93
6.56k
}
nsTString<char16_t>::FindCharInSet(char16_t const*, int) const
Line
Count
Source
83
26.8k
{
84
26.8k
  if (aOffset < 0)
85
0
    aOffset = 0;
86
26.8k
  else if (aOffset >= int32_t(this->mLength))
87
0
    return kNotFound;
88
26.8k
89
26.8k
  int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
90
26.8k
  if (result != kNotFound)
91
26.8k
    result += aOffset;
92
26.8k
  return result;
93
26.8k
}
94
95
96
/**
97
 * nsTString::RFindCharInSet
98
 */
99
100
template <typename T>
101
int32_t
102
nsTString<T>::RFindCharInSet(const char_type* aSet, int32_t aOffset) const
103
12
{
104
12
  // We want to pass a "data length" to ::RFindCharInSet
105
12
  if (aOffset < 0 || aOffset > int32_t(this->mLength))
106
12
    aOffset = this->mLength;
107
0
  else
108
0
    ++aOffset;
109
12
110
12
  return ::RFindCharInSet(this->mData, aOffset, aSet);
111
12
}
nsTString<char>::RFindCharInSet(char const*, int) const
Line
Count
Source
103
12
{
104
12
  // We want to pass a "data length" to ::RFindCharInSet
105
12
  if (aOffset < 0 || aOffset > int32_t(this->mLength))
106
12
    aOffset = this->mLength;
107
0
  else
108
0
    ++aOffset;
109
12
110
12
  return ::RFindCharInSet(this->mData, aOffset, aSet);
111
12
}
Unexecuted instantiation: nsTString<char16_t>::RFindCharInSet(char16_t const*, int) const
112
113
114
/**
115
   * nsTString::Mid
116
   */
117
118
template <typename T>
119
typename nsTString<T>::size_type
120
nsTString<T>::Mid(self_type& aResult, index_type aStartPos, size_type aLengthToCopy) const
121
0
{
122
0
  if (aStartPos == 0 && aLengthToCopy >= this->mLength)
123
0
    aResult = *this;
124
0
  else
125
0
    aResult = Substring(*this, aStartPos, aLengthToCopy);
126
0
127
0
  return aResult.mLength;
128
0
}
Unexecuted instantiation: nsTString<char>::Mid(nsTString<char>&, unsigned int, unsigned int) const
Unexecuted instantiation: nsTString<char16_t>::Mid(nsTString<char16_t>&, unsigned int, unsigned int) const
129
130
131
/**
132
 * nsTString::SetCharAt
133
 */
134
135
template <typename T>
136
bool
137
nsTString<T>::SetCharAt(char16_t aChar, uint32_t aIndex)
138
0
{
139
0
  if (aIndex >= this->mLength)
140
0
    return false;
141
0
142
0
  if (!this->EnsureMutable())
143
0
    this->AllocFailed(this->mLength);
144
0
145
0
  this->mData[aIndex] = char_type(aChar);
146
0
  return true;
147
0
}
Unexecuted instantiation: nsTString<char>::SetCharAt(char16_t, unsigned int)
Unexecuted instantiation: nsTString<char16_t>::SetCharAt(char16_t, unsigned int)
148
149
150
/**
151
 * nsTString::StripChars,StripChar,StripWhitespace
152
 */
153
154
template<typename T>
155
template<typename Q, typename EnableIfChar16>
156
void
157
nsTString<T>::StripChars(const incompatible_char_type* aSet)
158
0
{
159
0
  if (!StripChars(aSet, mozilla::fallible)) {
160
0
    this->AllocFailed(this->mLength);
161
0
  }
162
0
}
163
164
template<typename T>
165
template<typename Q, typename EnableIfChar16>
166
bool
167
nsTString<T>::StripChars(const incompatible_char_type* aSet, const fallible_t&)
168
0
{
169
0
  if (!this->EnsureMutable()) {
170
0
    return false;
171
0
  }
172
0
173
0
  this->mLength = nsBufferRoutines<T>::strip_chars(this->mData, this->mLength, aSet);
174
0
  return true;
175
0
}
176
177
template<typename T>
178
void
179
nsTString<T>::StripChars(const char_type* aSet)
180
1
{
181
1
  nsTSubstring<T>::StripChars(aSet);
182
1
}
nsTString<char>::StripChars(char const*)
Line
Count
Source
180
1
{
181
1
  nsTSubstring<T>::StripChars(aSet);
182
1
}
Unexecuted instantiation: nsTString<char16_t>::StripChars(char16_t const*)
183
184
template <typename T>
185
void
186
nsTString<T>::StripWhitespace()
187
0
{
188
0
  if (!StripWhitespace(mozilla::fallible)) {
189
0
    this->AllocFailed(this->mLength);
190
0
  }
191
0
}
Unexecuted instantiation: nsTString<char>::StripWhitespace()
Unexecuted instantiation: nsTString<char16_t>::StripWhitespace()
192
193
template <typename T>
194
bool
195
nsTString<T>::StripWhitespace(const fallible_t&)
196
633
{
197
633
  if (!this->EnsureMutable()) {
198
0
    return false;
199
0
  }
200
633
201
633
  this->StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
202
633
  return true;
203
633
}
nsTString<char>::StripWhitespace(std::nothrow_t const&)
Line
Count
Source
196
633
{
197
633
  if (!this->EnsureMutable()) {
198
0
    return false;
199
0
  }
200
633
201
633
  this->StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
202
633
  return true;
203
633
}
Unexecuted instantiation: nsTString<char16_t>::StripWhitespace(std::nothrow_t const&)
204
205
/**
206
 * nsTString::ReplaceChar,ReplaceSubstring
207
 */
208
209
template <typename T>
210
void
211
nsTString<T>::ReplaceChar(char_type aOldChar, char_type aNewChar)
212
12
{
213
12
  if (!this->EnsureMutable()) // XXX do this lazily?
214
0
    this->AllocFailed(this->mLength);
215
12
216
102
  for (uint32_t i=0; i<this->mLength; ++i)
217
90
  {
218
90
    if (this->mData[i] == aOldChar)
219
12
      this->mData[i] = aNewChar;
220
90
  }
221
12
}
nsTString<char>::ReplaceChar(char, char)
Line
Count
Source
212
12
{
213
12
  if (!this->EnsureMutable()) // XXX do this lazily?
214
0
    this->AllocFailed(this->mLength);
215
12
216
102
  for (uint32_t i=0; i<this->mLength; ++i)
217
90
  {
218
90
    if (this->mData[i] == aOldChar)
219
12
      this->mData[i] = aNewChar;
220
90
  }
221
12
}
Unexecuted instantiation: nsTString<char16_t>::ReplaceChar(char16_t, char16_t)
222
223
template <typename T>
224
void
225
nsTString<T>::ReplaceChar(const char_type* aSet, char_type aNewChar)
226
0
{
227
0
  if (!this->EnsureMutable()) // XXX do this lazily?
228
0
    this->AllocFailed(this->mLength);
229
0
230
0
  char_type* data = this->mData;
231
0
  uint32_t lenRemaining = this->mLength;
232
0
233
0
  while (lenRemaining)
234
0
  {
235
0
    int32_t i = ::FindCharInSet(data, lenRemaining, aSet);
236
0
    if (i == kNotFound)
237
0
      break;
238
0
239
0
    data[i++] = aNewChar;
240
0
    data += i;
241
0
    lenRemaining -= i;
242
0
  }
243
0
}
Unexecuted instantiation: nsTString<char>::ReplaceChar(char const*, char)
Unexecuted instantiation: nsTString<char16_t>::ReplaceChar(char16_t const*, char16_t)
244
245
void ReleaseData(void* aData, nsAString::DataFlags aFlags);
246
247
template <typename T>
248
void
249
nsTString<T>::ReplaceSubstring(const char_type* aTarget,
250
                               const char_type* aNewValue)
251
349
{
252
349
  ReplaceSubstring(nsTDependentString<T>(aTarget),
253
349
                   nsTDependentString<T>(aNewValue));
254
349
}
nsTString<char>::ReplaceSubstring(char const*, char const*)
Line
Count
Source
251
349
{
252
349
  ReplaceSubstring(nsTDependentString<T>(aTarget),
253
349
                   nsTDependentString<T>(aNewValue));
254
349
}
Unexecuted instantiation: nsTString<char16_t>::ReplaceSubstring(char16_t const*, char16_t const*)
255
256
template <typename T>
257
bool
258
nsTString<T>::ReplaceSubstring(const char_type* aTarget,
259
                               const char_type* aNewValue,
260
                               const fallible_t& aFallible)
261
0
{
262
0
  return ReplaceSubstring(nsTDependentString<T>(aTarget),
263
0
                          nsTDependentString<T>(aNewValue),
264
0
                          aFallible);
265
0
}
Unexecuted instantiation: nsTString<char>::ReplaceSubstring(char const*, char const*, std::nothrow_t const&)
Unexecuted instantiation: nsTString<char16_t>::ReplaceSubstring(char16_t const*, char16_t const*, std::nothrow_t const&)
266
267
template <typename T>
268
void
269
nsTString<T>::ReplaceSubstring(const self_type& aTarget,
270
                               const self_type& aNewValue)
271
349
{
272
349
  if (!ReplaceSubstring(aTarget, aNewValue, mozilla::fallible)) {
273
0
    // Note that this may wildly underestimate the allocation that failed, as
274
0
    // we could have been replacing multiple copies of aTarget.
275
0
    this->AllocFailed(this->mLength + (aNewValue.Length() - aTarget.Length()));
276
0
  }
277
349
}
nsTString<char>::ReplaceSubstring(nsTString<char> const&, nsTString<char> const&)
Line
Count
Source
271
349
{
272
349
  if (!ReplaceSubstring(aTarget, aNewValue, mozilla::fallible)) {
273
0
    // Note that this may wildly underestimate the allocation that failed, as
274
0
    // we could have been replacing multiple copies of aTarget.
275
0
    this->AllocFailed(this->mLength + (aNewValue.Length() - aTarget.Length()));
276
0
  }
277
349
}
Unexecuted instantiation: nsTString<char16_t>::ReplaceSubstring(nsTString<char16_t> const&, nsTString<char16_t> const&)
278
279
template <typename T>
280
bool
281
nsTString<T>::ReplaceSubstring(const self_type& aTarget,
282
                               const self_type& aNewValue,
283
                               const fallible_t&)
284
349
{
285
349
  if (aTarget.Length() == 0)
286
0
    return true;
287
349
288
349
  // Remember all of the non-matching parts.
289
349
  AutoTArray<Segment, 16> nonMatching;
290
349
  uint32_t i = 0;
291
349
  mozilla::CheckedUint32 newLength;
292
349
  while (true)
293
349
  {
294
349
    int32_t r = FindSubstring(this->mData + i, this->mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
295
349
    int32_t until = (r == kNotFound) ? this->mLength - i : r;
296
349
    nonMatching.AppendElement(Segment(i, until));
297
349
    newLength += until;
298
349
    if (r == kNotFound) {
299
349
      break;
300
349
    }
301
0
302
0
    newLength += aNewValue.Length();
303
0
    i += r + aTarget.Length();
304
0
    if (i >= this->mLength) {
305
0
      // Add an auxiliary entry at the end of the list to help as an edge case
306
0
      // for the algorithms below.
307
0
      nonMatching.AppendElement(Segment(this->mLength, 0));
308
0
      break;
309
0
    }
310
0
  }
311
349
312
349
  if (!newLength.isValid()) {
313
0
    return false;
314
0
  }
315
349
316
349
  // If there's only one non-matching segment, then the target string was not
317
349
  // found, and there's nothing to do.
318
349
  if (nonMatching.Length() == 1) {
319
349
    MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == this->mLength,
320
349
               "We should have the correct non-matching segment.");
321
349
    return true;
322
349
  }
323
0
324
0
  // Make sure that we can mutate our buffer.
325
0
  // Note that we always allocate at least an this->mLength sized buffer, because the
326
0
  // rest of the algorithm relies on having access to all of the original
327
0
  // string.  In other words, we over-allocate in the shrinking case.
328
0
  uint32_t oldLen = this->mLength;
329
0
  mozilla::Result<uint32_t, nsresult> r =
330
0
    this->StartBulkWriteImpl(XPCOM_MAX(oldLen, newLength.value()), oldLen);
331
0
  if (r.isErr()) {
332
0
    return false;
333
0
  }
334
0
335
0
  if (aTarget.Length() >= aNewValue.Length()) {
336
0
    // In the shrinking case, start filling the buffer from the beginning.
337
0
    const uint32_t delta = (aTarget.Length() - aNewValue.Length());
338
0
    for (i = 1; i < nonMatching.Length(); ++i) {
339
0
      // When we move the i'th non-matching segment into position, we need to
340
0
      // account for the characters deleted by the previous |i| replacements by
341
0
      // subtracting |i * delta|.
342
0
      const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
343
0
      char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin - i * delta;
344
0
      // Write the i'th replacement immediately before the new i'th non-matching
345
0
      // segment.
346
0
      char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
347
0
                        aNewValue.Data(), aNewValue.Length());
348
0
      char_traits::move(destinationSegmentPtr, sourceSegmentPtr,
349
0
                        nonMatching[i].mLength);
350
0
    }
351
0
  } else {
352
0
    // In the growing case, start filling the buffer from the end.
353
0
    const uint32_t delta = (aNewValue.Length() - aTarget.Length());
354
0
    for (i = nonMatching.Length() - 1; i > 0; --i) {
355
0
      // When we move the i'th non-matching segment into position, we need to
356
0
      // account for the characters added by the previous |i| replacements by
357
0
      // adding |i * delta|.
358
0
      const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
359
0
      char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin + i * delta;
360
0
      char_traits::move(destinationSegmentPtr, sourceSegmentPtr,
361
0
                        nonMatching[i].mLength);
362
0
      // Write the i'th replacement immediately before the new i'th non-matching
363
0
      // segment.
364
0
      char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
365
0
                        aNewValue.Data(), aNewValue.Length());
366
0
    }
367
0
  }
368
0
369
0
  // Adjust the length and make sure the string is null terminated.
370
0
  this->FinishBulkWriteImpl(newLength.value());
371
0
372
0
  return true;
373
0
}
nsTString<char>::ReplaceSubstring(nsTString<char> const&, nsTString<char> const&, std::nothrow_t const&)
Line
Count
Source
284
349
{
285
349
  if (aTarget.Length() == 0)
286
0
    return true;
287
349
288
349
  // Remember all of the non-matching parts.
289
349
  AutoTArray<Segment, 16> nonMatching;
290
349
  uint32_t i = 0;
291
349
  mozilla::CheckedUint32 newLength;
292
349
  while (true)
293
349
  {
294
349
    int32_t r = FindSubstring(this->mData + i, this->mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
295
349
    int32_t until = (r == kNotFound) ? this->mLength - i : r;
296
349
    nonMatching.AppendElement(Segment(i, until));
297
349
    newLength += until;
298
349
    if (r == kNotFound) {
299
349
      break;
300
349
    }
301
0
302
0
    newLength += aNewValue.Length();
303
0
    i += r + aTarget.Length();
304
0
    if (i >= this->mLength) {
305
0
      // Add an auxiliary entry at the end of the list to help as an edge case
306
0
      // for the algorithms below.
307
0
      nonMatching.AppendElement(Segment(this->mLength, 0));
308
0
      break;
309
0
    }
310
0
  }
311
349
312
349
  if (!newLength.isValid()) {
313
0
    return false;
314
0
  }
315
349
316
349
  // If there's only one non-matching segment, then the target string was not
317
349
  // found, and there's nothing to do.
318
349
  if (nonMatching.Length() == 1) {
319
349
    MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == this->mLength,
320
349
               "We should have the correct non-matching segment.");
321
349
    return true;
322
349
  }
323
0
324
0
  // Make sure that we can mutate our buffer.
325
0
  // Note that we always allocate at least an this->mLength sized buffer, because the
326
0
  // rest of the algorithm relies on having access to all of the original
327
0
  // string.  In other words, we over-allocate in the shrinking case.
328
0
  uint32_t oldLen = this->mLength;
329
0
  mozilla::Result<uint32_t, nsresult> r =
330
0
    this->StartBulkWriteImpl(XPCOM_MAX(oldLen, newLength.value()), oldLen);
331
0
  if (r.isErr()) {
332
0
    return false;
333
0
  }
334
0
335
0
  if (aTarget.Length() >= aNewValue.Length()) {
336
0
    // In the shrinking case, start filling the buffer from the beginning.
337
0
    const uint32_t delta = (aTarget.Length() - aNewValue.Length());
338
0
    for (i = 1; i < nonMatching.Length(); ++i) {
339
0
      // When we move the i'th non-matching segment into position, we need to
340
0
      // account for the characters deleted by the previous |i| replacements by
341
0
      // subtracting |i * delta|.
342
0
      const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
343
0
      char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin - i * delta;
344
0
      // Write the i'th replacement immediately before the new i'th non-matching
345
0
      // segment.
346
0
      char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
347
0
                        aNewValue.Data(), aNewValue.Length());
348
0
      char_traits::move(destinationSegmentPtr, sourceSegmentPtr,
349
0
                        nonMatching[i].mLength);
350
0
    }
351
0
  } else {
352
0
    // In the growing case, start filling the buffer from the end.
353
0
    const uint32_t delta = (aNewValue.Length() - aTarget.Length());
354
0
    for (i = nonMatching.Length() - 1; i > 0; --i) {
355
0
      // When we move the i'th non-matching segment into position, we need to
356
0
      // account for the characters added by the previous |i| replacements by
357
0
      // adding |i * delta|.
358
0
      const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
359
0
      char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin + i * delta;
360
0
      char_traits::move(destinationSegmentPtr, sourceSegmentPtr,
361
0
                        nonMatching[i].mLength);
362
0
      // Write the i'th replacement immediately before the new i'th non-matching
363
0
      // segment.
364
0
      char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
365
0
                        aNewValue.Data(), aNewValue.Length());
366
0
    }
367
0
  }
368
0
369
0
  // Adjust the length and make sure the string is null terminated.
370
0
  this->FinishBulkWriteImpl(newLength.value());
371
0
372
0
  return true;
373
0
}
Unexecuted instantiation: nsTString<char16_t>::ReplaceSubstring(nsTString<char16_t> const&, nsTString<char16_t> const&, std::nothrow_t const&)
374
375
/**
376
 * nsTString::Trim
377
 */
378
379
template <typename T>
380
void
381
nsTString<T>::Trim(const char* aSet, bool aTrimLeading, bool aTrimTrailing, bool aIgnoreQuotes)
382
1.41M
{
383
1.41M
  // the old implementation worried about aSet being null :-/
384
1.41M
  if (!aSet)
385
0
    return;
386
1.41M
387
1.41M
  char_type* start = this->mData;
388
1.41M
  char_type* end   = this->mData + this->mLength;
389
1.41M
390
1.41M
  // skip over quotes if requested
391
1.41M
  if (aIgnoreQuotes && this->mLength > 2 && this->mData[0] == this->mData[this->mLength - 1] &&
392
1.41M
      (this->mData[0] == '\'' || this->mData[0] == '"'))
393
0
  {
394
0
    ++start;
395
0
    --end;
396
0
  }
397
1.41M
398
1.41M
  uint32_t setLen = nsCharTraits<char>::length(aSet);
399
1.41M
400
1.41M
  if (aTrimLeading)
401
2.33k
  {
402
2.33k
    uint32_t cutStart = start - this->mData;
403
2.33k
    uint32_t cutLength = 0;
404
2.33k
405
2.33k
    // walk forward from start to end
406
2.33k
    for (; start != end; ++start, ++cutLength)
407
2.33k
    {
408
2.33k
      int32_t pos = FindChar1(aSet, setLen, 0, *start, setLen);
409
2.33k
      if (pos == kNotFound)
410
2.33k
        break;
411
2.33k
    }
412
2.33k
413
2.33k
    if (cutLength)
414
0
    {
415
0
      this->Cut(cutStart, cutLength);
416
0
417
0
      // reset iterators
418
0
      start = this->mData + cutStart;
419
0
      end   = this->mData + this->mLength - cutStart;
420
0
    }
421
2.33k
  }
422
1.41M
423
1.41M
  if (aTrimTrailing)
424
1.41M
  {
425
1.41M
    uint32_t cutEnd = end - this->mData;
426
1.41M
    uint32_t cutLength = 0;
427
1.41M
428
1.41M
    // walk backward from end to start
429
1.41M
    --end;
430
2.47M
    for (; end >= start; --end, ++cutLength)
431
2.47M
    {
432
2.47M
      int32_t pos = FindChar1(aSet, setLen, 0, *end, setLen);
433
2.47M
      if (pos == kNotFound)
434
2.47M
        break;
435
2.47M
    }
436
1.41M
437
1.41M
    if (cutLength)
438
1.06M
      this->Cut(cutEnd - cutLength, cutLength);
439
1.41M
  }
440
1.41M
}
nsTString<char>::Trim(char const*, bool, bool, bool)
Line
Count
Source
382
2.33k
{
383
2.33k
  // the old implementation worried about aSet being null :-/
384
2.33k
  if (!aSet)
385
0
    return;
386
2.33k
387
2.33k
  char_type* start = this->mData;
388
2.33k
  char_type* end   = this->mData + this->mLength;
389
2.33k
390
2.33k
  // skip over quotes if requested
391
2.33k
  if (aIgnoreQuotes && this->mLength > 2 && this->mData[0] == this->mData[this->mLength - 1] &&
392
2.33k
      (this->mData[0] == '\'' || this->mData[0] == '"'))
393
0
  {
394
0
    ++start;
395
0
    --end;
396
0
  }
397
2.33k
398
2.33k
  uint32_t setLen = nsCharTraits<char>::length(aSet);
399
2.33k
400
2.33k
  if (aTrimLeading)
401
2.33k
  {
402
2.33k
    uint32_t cutStart = start - this->mData;
403
2.33k
    uint32_t cutLength = 0;
404
2.33k
405
2.33k
    // walk forward from start to end
406
2.33k
    for (; start != end; ++start, ++cutLength)
407
2.33k
    {
408
2.33k
      int32_t pos = FindChar1(aSet, setLen, 0, *start, setLen);
409
2.33k
      if (pos == kNotFound)
410
2.33k
        break;
411
2.33k
    }
412
2.33k
413
2.33k
    if (cutLength)
414
0
    {
415
0
      this->Cut(cutStart, cutLength);
416
0
417
0
      // reset iterators
418
0
      start = this->mData + cutStart;
419
0
      end   = this->mData + this->mLength - cutStart;
420
0
    }
421
2.33k
  }
422
2.33k
423
2.33k
  if (aTrimTrailing)
424
2.33k
  {
425
2.33k
    uint32_t cutEnd = end - this->mData;
426
2.33k
    uint32_t cutLength = 0;
427
2.33k
428
2.33k
    // walk backward from end to start
429
2.33k
    --end;
430
2.33k
    for (; end >= start; --end, ++cutLength)
431
2.33k
    {
432
2.33k
      int32_t pos = FindChar1(aSet, setLen, 0, *end, setLen);
433
2.33k
      if (pos == kNotFound)
434
2.33k
        break;
435
2.33k
    }
436
2.33k
437
2.33k
    if (cutLength)
438
6
      this->Cut(cutEnd - cutLength, cutLength);
439
2.33k
  }
440
2.33k
}
nsTString<char16_t>::Trim(char const*, bool, bool, bool)
Line
Count
Source
382
1.41M
{
383
1.41M
  // the old implementation worried about aSet being null :-/
384
1.41M
  if (!aSet)
385
0
    return;
386
1.41M
387
1.41M
  char_type* start = this->mData;
388
1.41M
  char_type* end   = this->mData + this->mLength;
389
1.41M
390
1.41M
  // skip over quotes if requested
391
1.41M
  if (aIgnoreQuotes && this->mLength > 2 && this->mData[0] == this->mData[this->mLength - 1] &&
392
1.41M
      (this->mData[0] == '\'' || this->mData[0] == '"'))
393
0
  {
394
0
    ++start;
395
0
    --end;
396
0
  }
397
1.41M
398
1.41M
  uint32_t setLen = nsCharTraits<char>::length(aSet);
399
1.41M
400
1.41M
  if (aTrimLeading)
401
0
  {
402
0
    uint32_t cutStart = start - this->mData;
403
0
    uint32_t cutLength = 0;
404
0
405
0
    // walk forward from start to end
406
0
    for (; start != end; ++start, ++cutLength)
407
0
    {
408
0
      int32_t pos = FindChar1(aSet, setLen, 0, *start, setLen);
409
0
      if (pos == kNotFound)
410
0
        break;
411
0
    }
412
0
413
0
    if (cutLength)
414
0
    {
415
0
      this->Cut(cutStart, cutLength);
416
0
417
0
      // reset iterators
418
0
      start = this->mData + cutStart;
419
0
      end   = this->mData + this->mLength - cutStart;
420
0
    }
421
0
  }
422
1.41M
423
1.41M
  if (aTrimTrailing)
424
1.41M
  {
425
1.41M
    uint32_t cutEnd = end - this->mData;
426
1.41M
    uint32_t cutLength = 0;
427
1.41M
428
1.41M
    // walk backward from end to start
429
1.41M
    --end;
430
2.47M
    for (; end >= start; --end, ++cutLength)
431
2.47M
    {
432
2.47M
      int32_t pos = FindChar1(aSet, setLen, 0, *end, setLen);
433
2.47M
      if (pos == kNotFound)
434
2.47M
        break;
435
2.47M
    }
436
1.41M
437
1.41M
    if (cutLength)
438
1.06M
      this->Cut(cutEnd - cutLength, cutLength);
439
1.41M
  }
440
1.41M
}
441
442
443
/**
444
 * nsTString::CompressWhitespace.
445
 */
446
447
template <typename T>
448
void
449
nsTString<T>::CompressWhitespace(bool aTrimLeading, bool aTrimTrailing)
450
24
{
451
24
  // Quick exit
452
24
  if (this->mLength == 0) {
453
9
    return;
454
9
  }
455
15
456
15
  if (!this->EnsureMutable())
457
0
    this->AllocFailed(this->mLength);
458
15
459
15
  const ASCIIMaskArray& mask = mozilla::ASCIIMask::MaskWhitespace();
460
15
461
15
  char_type* to   = this->mData;
462
15
  char_type* from = this->mData;
463
15
  char_type* end  = this->mData + this->mLength;
464
15
465
15
  // Compresses runs of whitespace down to a normal space ' ' and convert
466
15
  // any whitespace to a normal space.  This assumes that whitespace is
467
15
  // all standard 7-bit ASCII.
468
15
  bool skipWS = aTrimLeading;
469
402
  while (from < end) {
470
387
    uint32_t theChar = *from++;
471
387
    if (mozilla::ASCIIMask::IsMasked(mask, theChar)) {
472
3
      if (!skipWS) {
473
3
        *to++ = ' ';
474
3
        skipWS = true;
475
3
      }
476
384
    } else {
477
384
      *to++ = theChar;
478
384
      skipWS = false;
479
384
    }
480
387
  }
481
15
482
15
  // If we need to trim the trailing whitespace, back up one character.
483
15
  if (aTrimTrailing && skipWS && to > this->mData) {
484
0
    to--;
485
0
  }
486
15
487
15
  *to = char_type(0); // add the null
488
15
  this->mLength = to - this->mData;
489
15
}
nsTString<char>::CompressWhitespace(bool, bool)
Line
Count
Source
450
24
{
451
24
  // Quick exit
452
24
  if (this->mLength == 0) {
453
9
    return;
454
9
  }
455
15
456
15
  if (!this->EnsureMutable())
457
0
    this->AllocFailed(this->mLength);
458
15
459
15
  const ASCIIMaskArray& mask = mozilla::ASCIIMask::MaskWhitespace();
460
15
461
15
  char_type* to   = this->mData;
462
15
  char_type* from = this->mData;
463
15
  char_type* end  = this->mData + this->mLength;
464
15
465
15
  // Compresses runs of whitespace down to a normal space ' ' and convert
466
15
  // any whitespace to a normal space.  This assumes that whitespace is
467
15
  // all standard 7-bit ASCII.
468
15
  bool skipWS = aTrimLeading;
469
402
  while (from < end) {
470
387
    uint32_t theChar = *from++;
471
387
    if (mozilla::ASCIIMask::IsMasked(mask, theChar)) {
472
3
      if (!skipWS) {
473
3
        *to++ = ' ';
474
3
        skipWS = true;
475
3
      }
476
384
    } else {
477
384
      *to++ = theChar;
478
384
      skipWS = false;
479
384
    }
480
387
  }
481
15
482
15
  // If we need to trim the trailing whitespace, back up one character.
483
15
  if (aTrimTrailing && skipWS && to > this->mData) {
484
0
    to--;
485
0
  }
486
15
487
15
  *to = char_type(0); // add the null
488
15
  this->mLength = to - this->mData;
489
15
}
Unexecuted instantiation: nsTString<char16_t>::CompressWhitespace(bool, bool)