Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/nsTSubstring.h
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
// IWYU pragma: private, include "nsString.h"
7
8
#ifndef nsTSubstring_h
9
#define nsTSubstring_h
10
11
#include "mozilla/Casting.h"
12
#include "mozilla/DebugOnly.h"
13
#include "mozilla/IntegerPrintfMacros.h"
14
#include "mozilla/UniquePtr.h"
15
#include "mozilla/MemoryReporting.h"
16
#include "mozilla/IntegerTypeTraits.h"
17
#include "mozilla/Result.h"
18
#include "mozilla/Span.h"
19
#include "mozilla/Unused.h"
20
21
#include "nsTStringRepr.h"
22
23
#ifndef MOZILLA_INTERNAL_API
24
#error "Using XPCOM strings is limited to code linked into libxul."
25
#endif
26
27
// The max number of logically uninitialized code units to
28
// fill with a marker byte or to mark as unintialized for
29
// memory checking. (Limited to avoid quadratic behavior.)
30
const size_t kNsStringBufferMaxPoison = 16;
31
32
template <typename T> class nsTSubstringSplitter;
33
template <typename T> class nsTString;
34
template <typename T> class nsTSubstring;
35
36
namespace mozilla {
37
38
/**
39
 * This handle represents permission to perform low-level writes
40
 * the storage buffer of a string in a manner that's aware of the
41
 * actual capacity of the storage buffer allocation and that's
42
 * cache-friendly in the sense that the writing of zero terminator
43
 * for C compatibility can happen in linear memory access order
44
 * (i.e. the zero terminator write takes place after writing
45
 * new content to the string as opposed to the zero terminator
46
 * write happening first causing a non-linear memory write for
47
 * cache purposes).
48
 *
49
 * If you requested a prefix to be preserved when starting
50
 * or restarting the bulk write, the prefix is present at the
51
 * start of the buffer exposed by this handle as Span or
52
 * as a raw pointer, and it's your responsibility to start
53
 * writing after after the preserved prefix (which you
54
 * presumably wanted not to overwrite since you asked for
55
 * it to be preserved).
56
 *
57
 * In a success case, you must call Finish() with the new
58
 * length of the string. In failure cases, it's OK to return
59
 * early from the function whose local variable this handle is.
60
 * The destructor of this class takes care of putting the
61
 * string in a valid and mostly harmless state in that case
62
 * by setting the value of a non-empty string to a single
63
 * REPLACEMENT CHARACTER or in the case of nsACString that's
64
 * too short for a REPLACEMENT CHARACTER to fit, an ASCII
65
 * SUBSTITUTE.
66
 *
67
 * You must not allow this handle to outlive the string you
68
 * obtained it from.
69
 *
70
 * You must not access the string you obtained this handle
71
 * from in any way other than through this handle until
72
 * you call Finish() on the handle or the handle goes out
73
 * of scope.
74
 *
75
 * Once you've called Finish(), you must not call any
76
 * methods on this handle and must not use values previously
77
 * obtained.
78
 *
79
 * Once you call RestartBulkWrite(), you must not use
80
 * values previously obtained from this handle and must
81
 * reobtain the new corresponding values.
82
 */
83
template <typename T>
84
class BulkWriteHandle final {
85
  friend class nsTSubstring<T>;
86
public:
87
  typedef typename mozilla::detail::nsTStringRepr<T> base_string_type;
88
  typedef typename base_string_type::size_type size_type;
89
90
  /**
91
   * Pointer to the start of the writable buffer. Never nullptr.
92
   *
93
   * This pointer is valid until whichever of these happens first:
94
   *  1) Finish() is called
95
   *  2) RestartBulkWrite() is called
96
   *  3) BulkWriteHandle goes out of scope
97
   */
98
  T* Elements() const
99
0
  {
100
0
    MOZ_ASSERT(mString);
101
0
    return mString->mData;
102
0
  }
Unexecuted instantiation: mozilla::BulkWriteHandle<char>::Elements() const
Unexecuted instantiation: mozilla::BulkWriteHandle<char16_t>::Elements() const
103
104
  /**
105
   * How many code units can be written to the buffer.
106
   * (Note: This is not the same as the string's Length().)
107
   *
108
   * This value is valid until whichever of these happens first:
109
   *  1) Finish() is called
110
   *  2) RestartBulkWrite() is called
111
   *  3) BulkWriteHandle goes out of scope
112
   */
113
  size_type Length() const
114
0
  {
115
0
    MOZ_ASSERT(mString);
116
0
    return mCapacity;
117
0
  }
Unexecuted instantiation: mozilla::BulkWriteHandle<char16_t>::Length() const
Unexecuted instantiation: mozilla::BulkWriteHandle<char>::Length() const
118
119
  /**
120
   * Pointer past the end of the buffer.
121
   *
122
   * This pointer is valid until whichever of these happens first:
123
   *  1) Finish() is called
124
   *  2) RestartBulkWrite() is called
125
   *  3) BulkWriteHandle goes out of scope
126
   */
127
  T* End() const
128
  {
129
    return Elements() + Length();
130
  }
131
132
  /**
133
   * The writable buffer as Span.
134
   *
135
   * This Span is valid until whichever of these happens first:
136
   *  1) Finish() is called
137
   *  2) RestartBulkWrite() is called
138
   *  3) BulkWriteHandle goes out of scope
139
   */
140
  mozilla::Span<T> AsSpan() const
141
0
  {
142
0
    return mozilla::MakeSpan(Elements(), Length());
143
0
  }
Unexecuted instantiation: mozilla::BulkWriteHandle<char16_t>::AsSpan() const
Unexecuted instantiation: mozilla::BulkWriteHandle<char>::AsSpan() const
144
145
  /**
146
   * Autoconvert to the buffer as writable Span.
147
   *
148
   * This Span is valid until whichever of these happens first:
149
   *  1) Finish() is called
150
   *  2) RestartBulkWrite() is called
151
   *  3) BulkWriteHandle goes out of scope
152
   */
153
  operator mozilla::Span<T>() const
154
  {
155
    return AsSpan();
156
  }
157
158
  /**
159
   * Restart the bulk write with a different capacity.
160
   *
161
   * This method invalidates previous return values
162
   * of the other methods above.
163
   *
164
   * Can fail if out of memory leaving the buffer
165
   * in the state before this call.
166
   *
167
   * @param aCapacity the new requested capacity
168
   * @param aPrefixToPreserve the number of code units at
169
   *                          the start of the string to
170
   *                          copy over to the new buffer
171
   * @param aAllowShrinking whether the string is
172
   *                        allowed to attempt to
173
   *                        allocate a smaller buffer
174
   *                        for its content and copy
175
   *                        the data over.
176
   */
177
  mozilla::Result<mozilla::Ok, nsresult> RestartBulkWrite(size_type aCapacity,
178
                                                          size_type aPrefixToPreserve,
179
                                                          bool aAllowShrinking)
180
0
  {
181
0
    MOZ_ASSERT(mString);
182
0
    auto r = mString->StartBulkWriteImpl(aCapacity, aPrefixToPreserve, aAllowShrinking);
183
0
    if (MOZ_UNLIKELY(r.isErr())) {
184
0
      nsresult rv = r.unwrapErr();
185
0
      // MOZ_TRY or manual unwrapErr() without the intermediate
186
0
      // assignment complains about an incomplete type.
187
0
      // andThen() is not enabled on r.
188
0
      return mozilla::Err(rv);
189
0
    }
190
0
    mCapacity = r.unwrap();
191
0
    return mozilla::Ok();
192
0
  }
193
194
  /**
195
   * Indicate that the bulk write finished successfully.
196
   *
197
   * @param aLength the number of code units written;
198
   *                must not exceed Length()
199
   * @param aAllowShrinking whether the string is
200
   *                        allowed to attempt to
201
   *                        allocate a smaller buffer
202
   *                        for its content and copy
203
   *                        the data over.
204
   */
205
  void Finish(size_type aLength, bool aAllowShrinking)
206
0
  {
207
0
    MOZ_ASSERT(mString);
208
0
    MOZ_ASSERT(aLength <= mCapacity);
209
0
    if (!aLength) {
210
0
      // Truncate is safe even when the string is in an invalid state
211
0
      mString->Truncate();
212
0
      mString = nullptr;
213
0
      return;
214
0
    }
215
0
    if (aAllowShrinking) {
216
0
      mozilla::Unused << mString->StartBulkWriteImpl(aLength, aLength, true);
217
0
    }
218
0
    mString->FinishBulkWriteImpl(aLength);
219
0
    mString = nullptr;
220
0
  }
Unexecuted instantiation: mozilla::BulkWriteHandle<char16_t>::Finish(unsigned int, bool)
Unexecuted instantiation: mozilla::BulkWriteHandle<char>::Finish(unsigned int, bool)
221
222
  BulkWriteHandle(BulkWriteHandle&& aOther)
223
   : mString(aOther.Forget())
224
   , mCapacity(aOther.mCapacity)
225
0
  {
226
0
  }
227
228
  ~BulkWriteHandle()
229
0
  {
230
0
    if (!mString || !mCapacity) {
231
0
      return;
232
0
    }
233
0
    // The old zero terminator may be gone by now, so we need
234
0
    // to write a new one somewhere and make length match.
235
0
    // We can use a length between 1 and self.capacity.
236
0
    // The contents of the string can be partially uninitialized
237
0
    // or partially initialized in a way that would be dangerous
238
0
    // if parsed by some recipient. It's prudent to write something
239
0
    // same as the contents of the string. U+FFFD is the safest
240
0
    // placeholder, but when it doesn't fit, let's use ASCII
241
0
    // substitute. Merely truncating the string to a zero-length
242
0
    // string might be dangerous in some scenarios. See
243
0
    // https://www.unicode.org/reports/tr36/#Substituting_for_Ill_Formed_Subsequences
244
0
    // for closely related scenario.
245
0
    auto ptr = Elements();
246
0
    // Cast the pointer below to silence warnings
247
0
    if (sizeof(T) == 1) {
248
0
      unsigned char* charPtr = reinterpret_cast<unsigned char*>(ptr);
249
0
      if (mCapacity >= 3) {
250
0
        *charPtr++ = 0xEF;
251
0
        *charPtr++ = 0xBF;
252
0
        *charPtr++ = 0xBD;
253
0
        mString->mLength = 3;
254
0
      } else {
255
0
        *charPtr++ = 0x1A;
256
0
        mString->mLength = 1;
257
0
      }
258
0
      *charPtr = 0;
259
0
    } else if (sizeof(T) == 2){
260
0
      char16_t* charPtr = reinterpret_cast<char16_t*>(ptr);
261
0
      *charPtr++ = 0xFFFD;
262
0
      *charPtr = 0;
263
0
      mString->mLength = 1;
264
0
    } else {
265
0
      MOZ_ASSERT_UNREACHABLE("Only 8-bit and 16-bit code units supported.");
266
0
    }
267
0
  }
Unexecuted instantiation: mozilla::BulkWriteHandle<char16_t>::~BulkWriteHandle()
Unexecuted instantiation: mozilla::BulkWriteHandle<char>::~BulkWriteHandle()
268
269
  BulkWriteHandle() = delete;
270
  BulkWriteHandle(const BulkWriteHandle&) = delete;
271
  BulkWriteHandle& operator=(const BulkWriteHandle&) = delete;
272
273
private:
274
275
  BulkWriteHandle(nsTSubstring<T>* aString, size_type aCapacity)
276
   : mString(aString)
277
   , mCapacity(aCapacity)
278
  {}
279
280
  nsTSubstring<T>* Forget()
281
0
  {
282
0
    auto string = mString;
283
0
    mString = nullptr;
284
0
    return string;
285
0
  }
286
287
  nsTSubstring<T>* mString; // nullptr upon finish
288
  size_type        mCapacity;
289
};
290
291
} // namespace mozilla
292
293
/**
294
 * nsTSubstring is an abstract string class. From an API perspective, this
295
 * class is the root of the string class hierarchy. It represents a single
296
 * contiguous array of characters, which may or may not be null-terminated.
297
 * This type is not instantiated directly. A sub-class is instantiated
298
 * instead. For example, see nsTString.
299
 *
300
 * NAMES:
301
 *   nsAString for wide characters
302
 *   nsACString for narrow characters
303
 *
304
 */
305
template <typename T>
306
class nsTSubstring : public mozilla::detail::nsTStringRepr<T>
307
{
308
  friend class mozilla::BulkWriteHandle<T>;
309
public:
310
  typedef nsTSubstring<T> self_type;
311
312
  typedef nsTString<T> string_type;
313
314
  typedef typename mozilla::detail::nsTStringRepr<T> base_string_type;
315
  typedef typename base_string_type::substring_type substring_type;
316
317
  typedef typename base_string_type::fallible_t fallible_t;
318
319
  typedef typename base_string_type::char_type char_type;
320
  typedef typename base_string_type::char_traits char_traits;
321
  typedef typename base_string_type::incompatible_char_type incompatible_char_type;
322
323
  typedef typename base_string_type::substring_tuple_type substring_tuple_type;
324
325
  typedef typename base_string_type::const_iterator const_iterator;
326
  typedef typename base_string_type::iterator iterator;
327
328
  typedef typename base_string_type::comparator_type comparator_type;
329
330
  typedef typename base_string_type::const_char_iterator const_char_iterator;
331
332
  typedef typename base_string_type::index_type index_type;
333
  typedef typename base_string_type::size_type size_type;
334
335
  // These are only for internal use within the string classes:
336
  typedef typename base_string_type::DataFlags DataFlags;
337
  typedef typename base_string_type::ClassFlags ClassFlags;
338
339
  // this acts like a virtual destructor
340
  ~nsTSubstring()
341
206M
  {
342
206M
    Finalize();
343
206M
  }
nsTSubstring<char>::~nsTSubstring()
Line
Count
Source
341
189M
  {
342
189M
    Finalize();
343
189M
  }
nsTSubstring<char16_t>::~nsTSubstring()
Line
Count
Source
341
17.3M
  {
342
17.3M
    Finalize();
343
17.3M
  }
344
345
  /**
346
   * writing iterators
347
   *
348
   * BeginWriting() makes the string mutable (if it isn't
349
   * already) and returns (or writes into an outparam) a
350
   * pointer that provides write access to the string's buffer.
351
   *
352
   * Note: Consider if BulkWrite() suits your use case better
353
   * than BeginWriting() combined with SetLength().
354
   *
355
   * Note: Strings autoconvert into writable mozilla::Span,
356
   * which may suit your use case better than calling
357
   * BeginWriting() directly.
358
   *
359
   * When writing via the pointer obtained from BeginWriting(),
360
   * you are allowed to write at most the number of code units
361
   * indicated by Length() or, alternatively, write up to, but
362
   * not including, the position indicated by EndWriting().
363
   *
364
   * In particular, calling SetCapacity() does not affect what
365
   * the above paragraph says.
366
   */
367
368
  iterator BeginWriting()
369
  {
370
    if (!EnsureMutable()) {
371
      AllocFailed(base_string_type::mLength);
372
    }
373
374
    return base_string_type::mData;
375
  }
376
377
  iterator BeginWriting(const fallible_t&)
378
  {
379
    return EnsureMutable() ? base_string_type::mData : iterator(0);
380
  }
381
382
  iterator EndWriting()
383
  {
384
    if (!EnsureMutable()) {
385
      AllocFailed(base_string_type::mLength);
386
    }
387
388
    return base_string_type::mData + base_string_type::mLength;
389
  }
390
391
  iterator EndWriting(const fallible_t&)
392
  {
393
    return EnsureMutable() ? (base_string_type::mData + base_string_type::mLength) : iterator(0);
394
  }
395
396
  /**
397
   * Perform string to int conversion.
398
   * @param   aErrorCode will contain error if one occurs
399
   * @param   aRadix is the radix to use. Only 10 and 16 are supported.
400
   * @return  int rep of string value, and possible (out) error code
401
   */
402
  int32_t ToInteger(nsresult* aErrorCode, uint32_t aRadix = 10) const;
403
404
  /**
405
   * Perform string to 64-bit int conversion.
406
   * @param   aErrorCode will contain error if one occurs
407
   * @param   aRadix is the radix to use. Only 10 and 16 are supported.
408
   * @return  64-bit int rep of string value, and possible (out) error code
409
   */
410
  int64_t ToInteger64(nsresult* aErrorCode, uint32_t aRadix = 10) const;
411
412
  /**
413
   * assignment
414
   */
415
416
  void NS_FASTCALL Assign(char_type aChar);
417
  MOZ_MUST_USE bool NS_FASTCALL Assign(char_type aChar, const fallible_t&);
418
419
  void NS_FASTCALL Assign(const char_type* aData,
420
                          size_type aLength = size_type(-1));
421
  MOZ_MUST_USE bool NS_FASTCALL Assign(const char_type* aData,
422
                                       const fallible_t&);
423
  MOZ_MUST_USE bool NS_FASTCALL Assign(const char_type* aData,
424
                                       size_type aLength,
425
                                       const fallible_t&);
426
427
  void NS_FASTCALL Assign(const self_type&);
428
  MOZ_MUST_USE bool NS_FASTCALL Assign(const self_type&, const fallible_t&);
429
430
  void NS_FASTCALL Assign(self_type&&);
431
  MOZ_MUST_USE bool NS_FASTCALL Assign(self_type&&, const fallible_t&);
432
433
  void NS_FASTCALL Assign(const substring_tuple_type&);
434
  MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&,
435
                                       const fallible_t&);
436
437
#if defined(MOZ_USE_CHAR16_WRAPPER)
438
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
439
  void Assign(char16ptr_t aData)
440
  {
441
    Assign(static_cast<const char16_t*>(aData));
442
  }
443
444
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
445
  void Assign(char16ptr_t aData, size_type aLength)
446
  {
447
    Assign(static_cast<const char16_t*>(aData), aLength);
448
  }
449
450
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
451
  MOZ_MUST_USE bool Assign(char16ptr_t aData, size_type aLength,
452
                           const fallible_t& aFallible)
453
  {
454
    return Assign(static_cast<const char16_t*>(aData), aLength,
455
                  aFallible);
456
  }
457
#endif
458
459
  void NS_FASTCALL AssignASCII(const char* aData, size_type aLength);
460
  MOZ_MUST_USE bool NS_FASTCALL AssignASCII(const char* aData,
461
                                            size_type aLength,
462
                                            const fallible_t&);
463
464
  void NS_FASTCALL AssignASCII(const char* aData)
465
  {
466
    AssignASCII(aData, mozilla::AssertedCast<size_type, size_t>(strlen(aData)));
467
  }
468
  MOZ_MUST_USE bool NS_FASTCALL AssignASCII(const char* aData,
469
                                            const fallible_t& aFallible)
470
  {
471
    return AssignASCII(aData,
472
                       mozilla::AssertedCast<size_type, size_t>(strlen(aData)),
473
                       aFallible);
474
  }
475
476
  // AssignLiteral must ONLY be applied to an actual literal string, or
477
  // a character array *constant* declared without an explicit size.
478
  // Do not attempt to use it with a regular character pointer, or with a
479
  // non-constant chararacter array variable. Use AssignASCII for those.
480
  //
481
  // This method does not need a fallible version, because it uses the
482
  // POD buffer of the literal as the string's buffer without allocating.
483
  // The literal does not need to be ASCII. If this a 16-bit string, this
484
  // method takes a u"" literal. (The overload on 16-bit strings that takes
485
  // a "" literal takes only ASCII.)
486
  template<int N>
487
  void AssignLiteral(const char_type (&aStr)[N])
488
3.87k
  {
489
3.87k
    AssignLiteral(aStr, N - 1);
490
3.87k
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<25>(char const (&) [25])
void nsTSubstring<char>::AssignLiteral<4>(char const (&) [4])
Line
Count
Source
488
1
  {
489
1
    AssignLiteral(aStr, N - 1);
490
1
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<5>(char const (&) [5])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<17>(char const (&) [17])
void nsTSubstring<char>::AssignLiteral<8>(char const (&) [8])
Line
Count
Source
488
1
  {
489
1
    AssignLiteral(aStr, N - 1);
490
1
  }
void nsTSubstring<char>::AssignLiteral<12>(char const (&) [12])
Line
Count
Source
488
12
  {
489
12
    AssignLiteral(aStr, N - 1);
490
12
  }
void nsTSubstring<char>::AssignLiteral<27>(char const (&) [27])
Line
Count
Source
488
3
  {
489
3
    AssignLiteral(aStr, N - 1);
490
3
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<3>(char const (&) [3])
void nsTSubstring<char>::AssignLiteral<13>(char const (&) [13])
Line
Count
Source
488
1
  {
489
1
    AssignLiteral(aStr, N - 1);
490
1
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<23>(char const (&) [23])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<15>(char const (&) [15])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<10>(char const (&) [10])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<42>(char const (&) [42])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<22>(char const (&) [22])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<19>(char const (&) [19])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<20>(char const (&) [20])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<18>(char const (&) [18])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<26>(char const (&) [26])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<7>(char const (&) [7])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<16>(char const (&) [16])
void nsTSubstring<char>::AssignLiteral<6>(char const (&) [6])
Line
Count
Source
488
15
  {
489
15
    AssignLiteral(aStr, N - 1);
490
15
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<21>(char const (&) [21])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<21>(char16_t const (&) [21])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<5>(char16_t const (&) [5])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<9>(char16_t const (&) [9])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<25>(char16_t const (&) [25])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<3>(char16_t const (&) [3])
void nsTSubstring<char>::AssignLiteral<9>(char const (&) [9])
Line
Count
Source
488
1
  {
489
1
    AssignLiteral(aStr, N - 1);
490
1
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<28>(char const (&) [28])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<35>(char const (&) [35])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<2>(char const (&) [2])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<32>(char const (&) [32])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<46>(char const (&) [46])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<47>(char const (&) [47])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<426>(char const (&) [426])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<54>(char const (&) [54])
void nsTSubstring<char>::AssignLiteral<11>(char const (&) [11])
Line
Count
Source
488
3.84k
  {
489
3.84k
    AssignLiteral(aStr, N - 1);
490
3.84k
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<30>(char const (&) [30])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<50>(char const (&) [50])
void nsTSubstring<char>::AssignLiteral<1>(char const (&) [1])
Line
Count
Source
488
1
  {
489
1
    AssignLiteral(aStr, N - 1);
490
1
  }
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<38>(char const (&) [38])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<14>(char const (&) [14])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<24>(char const (&) [24])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<34>(char const (&) [34])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<29>(char const (&) [29])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<31>(char const (&) [31])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<10>(char16_t const (&) [10])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<33>(char const (&) [33])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<49>(char const (&) [49])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<4>(char16_t const (&) [4])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<6>(char16_t const (&) [6])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<2>(char16_t const (&) [2])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<20>(char16_t const (&) [20])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<8>(char16_t const (&) [8])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<12>(char16_t const (&) [12])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<14>(char16_t const (&) [14])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<45>(char const (&) [45])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<48>(char const (&) [48])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<86>(char const (&) [86])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<66>(char const (&) [66])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<19>(char16_t const (&) [19])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<17>(char16_t const (&) [17])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<37>(char const (&) [37])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<71>(char const (&) [71])
Unexecuted instantiation: void nsTSubstring<char>::AssignLiteral<53>(char const (&) [53])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<16>(char16_t const (&) [16])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<26>(char16_t const (&) [26])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<13>(char16_t const (&) [13])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<29>(char16_t const (&) [29])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<41>(char16_t const (&) [41])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<28>(char16_t const (&) [28])
491
492
  // AssignLiteral must ONLY be applied to an actual literal string, or
493
  // a character array *constant* declared without an explicit size.
494
  // Do not attempt to use it with a regular character pointer, or with a
495
  // non-constant chararacter array variable. Use AssignASCII for those.
496
  //
497
  // This method takes an 8-bit (ASCII-only!) string that is expanded
498
  // into a 16-bit string at run time causing a run-time allocation.
499
  // To avoid the run-time allocation (at the cost of the literal
500
  // taking twice the size in the binary), use the above overload that
501
  // takes a u"" string instead. Using the overload that takes a u""
502
  // literal is generally preferred when working with 16-bit strings.
503
  //
504
  // There is not a fallible version of this method because it only really
505
  // applies to small allocations that we wouldn't want to check anyway.
506
  template<int N, typename Q = T, typename EnableIfChar16 = typename mozilla::Char16OnlyT<Q>>
507
  void AssignLiteral(const incompatible_char_type (&aStr)[N])
508
0
  {
509
0
    AssignASCII(aStr, N - 1);
510
0
  }
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<14, char16_t, void>(char const (&) [14])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<8, char16_t, void>(char const (&) [8])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<5, char16_t, void>(char const (&) [5])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<6, char16_t, void>(char const (&) [6])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<7, char16_t, void>(char const (&) [7])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<9, char16_t, void>(char const (&) [9])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<4, char16_t, void>(char const (&) [4])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<24, char16_t, void>(char const (&) [24])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<17, char16_t, void>(char const (&) [17])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<18, char16_t, void>(char const (&) [18])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<3, char16_t, void>(char const (&) [3])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<1, char16_t, void>(char const (&) [1])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<2, char16_t, void>(char const (&) [2])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<51, char16_t, void>(char const (&) [51])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<29, char16_t, void>(char const (&) [29])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<16, char16_t, void>(char const (&) [16])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<10, char16_t, void>(char const (&) [10])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<25, char16_t, void>(char const (&) [25])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<23, char16_t, void>(char const (&) [23])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<37, char16_t, void>(char const (&) [37])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<30, char16_t, void>(char const (&) [30])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<13, char16_t, void>(char const (&) [13])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<12, char16_t, void>(char const (&) [12])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<11, char16_t, void>(char const (&) [11])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<19, char16_t, void>(char const (&) [19])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<20, char16_t, void>(char const (&) [20])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<15, char16_t, void>(char const (&) [15])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<35, char16_t, void>(char const (&) [35])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<22, char16_t, void>(char const (&) [22])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<21, char16_t, void>(char const (&) [21])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<32, char16_t, void>(char const (&) [32])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<40, char16_t, void>(char const (&) [40])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<27, char16_t, void>(char const (&) [27])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<28, char16_t, void>(char const (&) [28])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<39, char16_t, void>(char const (&) [39])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<91, char16_t, void>(char const (&) [91])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<56, char16_t, void>(char const (&) [56])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<53, char16_t, void>(char const (&) [53])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<41, char16_t, void>(char const (&) [41])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<31, char16_t, void>(char const (&) [31])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<154, char16_t, void>(char const (&) [154])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<38, char16_t, void>(char const (&) [38])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<58, char16_t, void>(char const (&) [58])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<26, char16_t, void>(char const (&) [26])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<122, char16_t, void>(char const (&) [122])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<101, char16_t, void>(char const (&) [101])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<249, char16_t, void>(char const (&) [249])
Unexecuted instantiation: void nsTSubstring<char16_t>::AssignLiteral<148, char16_t, void>(char const (&) [148])
511
512
  self_type& operator=(char_type aChar)
513
  {
514
    Assign(aChar);
515
    return *this;
516
  }
517
  self_type& operator=(const char_type* aData)
518
  {
519
    Assign(aData);
520
    return *this;
521
  }
522
#if defined(MOZ_USE_CHAR16_WRAPPER)
523
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
524
  self_type& operator=(char16ptr_t aData)
525
  {
526
    Assign(aData);
527
    return *this;
528
  }
529
#endif
530
  self_type& operator=(const self_type& aStr)
531
10.0M
  {
532
10.0M
    Assign(aStr);
533
10.0M
    return *this;
534
10.0M
  }
535
  self_type& operator=(self_type&& aStr)
536
  {
537
    Assign(std::move(aStr));
538
    return *this;
539
  }
540
  self_type& operator=(const substring_tuple_type& aTuple)
541
  {
542
    Assign(aTuple);
543
    return *this;
544
  }
545
546
  // Adopt a heap-allocated char sequence for this string; is Voided if aData
547
  // is null. Useful for e.g. converting an strdup'd C string into an
548
  // nsCString. See also getter_Copies(), which is a useful wrapper.
549
  void NS_FASTCALL Adopt(char_type* aData, size_type aLength = size_type(-1));
550
551
552
  /**
553
   * buffer manipulation
554
   */
555
556
  void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength,
557
                           char_type aChar);
558
  MOZ_MUST_USE bool NS_FASTCALL Replace(index_type aCutStart,
559
                                        size_type aCutLength,
560
                                        char_type aChar,
561
                                        const fallible_t&);
562
  void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength,
563
                           const char_type* aData,
564
                           size_type aLength = size_type(-1));
565
  MOZ_MUST_USE bool NS_FASTCALL Replace(index_type aCutStart,
566
                                        size_type aCutLength,
567
                                        const char_type* aData,
568
                                        size_type aLength,
569
                                        const fallible_t&);
570
  void Replace(index_type aCutStart, size_type aCutLength,
571
               const self_type& aStr)
572
  {
573
    Replace(aCutStart, aCutLength, aStr.Data(), aStr.Length());
574
  }
575
  MOZ_MUST_USE bool Replace(index_type aCutStart,
576
                            size_type aCutLength,
577
                            const self_type& aStr,
578
                            const fallible_t& aFallible)
579
  {
580
    return Replace(aCutStart, aCutLength, aStr.Data(), aStr.Length(),
581
                   aFallible);
582
  }
583
  void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength,
584
                           const substring_tuple_type& aTuple);
585
586
  void NS_FASTCALL ReplaceASCII(index_type aCutStart, size_type aCutLength,
587
                                const char* aData,
588
                                size_type aLength = size_type(-1));
589
590
  MOZ_MUST_USE bool NS_FASTCALL ReplaceASCII(index_type aCutStart, size_type aCutLength,
591
                                             const char* aData,
592
                                             size_type aLength,
593
                                             const fallible_t&);
594
595
  // ReplaceLiteral must ONLY be applied to an actual literal string.
596
  // Do not attempt to use it with a regular char* pointer, or with a char
597
  // array variable. Use Replace or ReplaceASCII for those.
598
  template<int N>
599
  void ReplaceLiteral(index_type aCutStart, size_type aCutLength,
600
                      const char_type (&aStr)[N])
601
0
  {
602
0
    ReplaceLiteral(aCutStart, aCutLength, aStr, N - 1);
603
0
  }
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<3>(unsigned int, unsigned int, char const (&) [3])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<8>(unsigned int, unsigned int, char const (&) [8])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<5>(unsigned int, unsigned int, char const (&) [5])
Unexecuted instantiation: void nsTSubstring<char16_t>::ReplaceLiteral<2>(unsigned int, unsigned int, char16_t const (&) [2])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<12>(unsigned int, unsigned int, char const (&) [12])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<13>(unsigned int, unsigned int, char const (&) [13])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<6>(unsigned int, unsigned int, char const (&) [6])
Unexecuted instantiation: void nsTSubstring<char16_t>::ReplaceLiteral<6>(unsigned int, unsigned int, char16_t const (&) [6])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<15>(unsigned int, unsigned int, char const (&) [15])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<11>(unsigned int, unsigned int, char const (&) [11])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<10>(unsigned int, unsigned int, char const (&) [10])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<1>(unsigned int, unsigned int, char const (&) [1])
Unexecuted instantiation: void nsTSubstring<char>::ReplaceLiteral<22>(unsigned int, unsigned int, char const (&) [22])
604
605
  void Append(char_type aChar);
606
607
  MOZ_MUST_USE bool Append(char_type aChar, const fallible_t& aFallible);
608
609
  void Append(const char_type* aData, size_type aLength = size_type(-1));
610
611
  MOZ_MUST_USE bool Append(const char_type* aData,
612
                           size_type aLength,
613
                           const fallible_t& aFallible);
614
615
#if defined(MOZ_USE_CHAR16_WRAPPER)
616
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
617
  void Append(char16ptr_t aData, size_type aLength = size_type(-1))
618
  {
619
    Append(static_cast<const char16_t*>(aData), aLength);
620
  }
621
#endif
622
623
  void Append(const self_type& aStr);
624
625
  MOZ_MUST_USE bool Append(const self_type& aStr, const fallible_t& aFallible);
626
627
  void Append(const substring_tuple_type& aTuple);
628
629
  MOZ_MUST_USE bool Append(const substring_tuple_type& aTuple, const fallible_t& aFallible);
630
631
  void AppendASCII(const char* aData, size_type aLength = size_type(-1));
632
633
  MOZ_MUST_USE bool AppendASCII(const char* aData,
634
                                const fallible_t& aFallible);
635
636
  MOZ_MUST_USE bool AppendASCII(const char* aData,
637
                                size_type aLength,
638
                                const fallible_t& aFallible);
639
640
  // Appends a literal string ("" literal in the 8-bit case and u"" literal
641
  // in the 16-bit case) to the string.
642
  //
643
  // AppendLiteral must ONLY be applied to an actual literal string.
644
  // Do not attempt to use it with a regular character pointer, or with a
645
  // character array variable. Use Append or AppendASCII for those.
646
  template<int N>
647
  void AppendLiteral(const char_type (&aStr)[N])
648
9.33k
  {
649
9.33k
    // The case where base_string_type::mLength is zero is intentionally
650
9.33k
    // left unoptimized (could be optimized as call to AssignLiteral),
651
9.33k
    // because it's rare/nonexistent. If you add that optimization,
652
9.33k
    // please be sure to also check that
653
9.33k
    // !(base_string_type::mDataFlags & DataFlags::REFCOUNTED)
654
9.33k
    // to avoid undoing the effects of SetCapacity().
655
9.33k
    Append(aStr, N - 1);
656
9.33k
  }
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<20>(char const (&) [20])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<9>(char const (&) [9])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<8>(char const (&) [8])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<3>(char const (&) [3])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<7>(char const (&) [7])
void nsTSubstring<char>::AppendLiteral<5>(char const (&) [5])
Line
Count
Source
648
1.59k
  {
649
1.59k
    // The case where base_string_type::mLength is zero is intentionally
650
1.59k
    // left unoptimized (could be optimized as call to AssignLiteral),
651
1.59k
    // because it's rare/nonexistent. If you add that optimization,
652
1.59k
    // please be sure to also check that
653
1.59k
    // !(base_string_type::mDataFlags & DataFlags::REFCOUNTED)
654
1.59k
    // to avoid undoing the effects of SetCapacity().
655
1.59k
    Append(aStr, N - 1);
656
1.59k
  }
void nsTSubstring<char>::AppendLiteral<11>(char const (&) [11])
Line
Count
Source
648
5
  {
649
5
    // The case where base_string_type::mLength is zero is intentionally
650
5
    // left unoptimized (could be optimized as call to AssignLiteral),
651
5
    // because it's rare/nonexistent. If you add that optimization,
652
5
    // please be sure to also check that
653
5
    // !(base_string_type::mDataFlags & DataFlags::REFCOUNTED)
654
5
    // to avoid undoing the effects of SetCapacity().
655
5
    Append(aStr, N - 1);
656
5
  }
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<6>(char const (&) [6])
void nsTSubstring<char>::AppendLiteral<4>(char const (&) [4])
Line
Count
Source
648
5.77k
  {
649
5.77k
    // The case where base_string_type::mLength is zero is intentionally
650
5.77k
    // left unoptimized (could be optimized as call to AssignLiteral),
651
5.77k
    // because it's rare/nonexistent. If you add that optimization,
652
5.77k
    // please be sure to also check that
653
5.77k
    // !(base_string_type::mDataFlags & DataFlags::REFCOUNTED)
654
5.77k
    // to avoid undoing the effects of SetCapacity().
655
5.77k
    Append(aStr, N - 1);
656
5.77k
  }
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<10>(char const (&) [10])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<15>(char const (&) [15])
void nsTSubstring<char>::AppendLiteral<2>(char const (&) [2])
Line
Count
Source
648
1.95k
  {
649
1.95k
    // The case where base_string_type::mLength is zero is intentionally
650
1.95k
    // left unoptimized (could be optimized as call to AssignLiteral),
651
1.95k
    // because it's rare/nonexistent. If you add that optimization,
652
1.95k
    // please be sure to also check that
653
1.95k
    // !(base_string_type::mDataFlags & DataFlags::REFCOUNTED)
654
1.95k
    // to avoid undoing the effects of SetCapacity().
655
1.95k
    Append(aStr, N - 1);
656
1.95k
  }
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<12>(char const (&) [12])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<25>(char const (&) [25])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<30>(char const (&) [30])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<19>(char const (&) [19])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<54>(char const (&) [54])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<362>(char const (&) [362])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<16>(char const (&) [16])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<45>(char const (&) [45])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<14>(char const (&) [14])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<31>(char const (&) [31])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<24>(char const (&) [24])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<4397>(char const (&) [4397])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<41>(char const (&) [41])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<955>(char const (&) [955])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<841>(char const (&) [841])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<13>(char const (&) [13])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<37>(char const (&) [37])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<108>(char const (&) [108])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<32>(char const (&) [32])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<26>(char const (&) [26])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<23>(char const (&) [23])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<52>(char const (&) [52])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<22>(char const (&) [22])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<17>(char const (&) [17])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<46>(char const (&) [46])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<119>(char const (&) [119])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<137>(char const (&) [137])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<66>(char const (&) [66])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<43>(char const (&) [43])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<18>(char const (&) [18])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<48>(char const (&) [48])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<51>(char const (&) [51])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<28>(char const (&) [28])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<39>(char const (&) [39])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<400>(char const (&) [400])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<79>(char const (&) [79])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<90>(char const (&) [90])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<96>(char const (&) [96])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<4>(char16_t const (&) [4])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<2>(char16_t const (&) [2])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<5>(char16_t const (&) [5])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<62>(char const (&) [62])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<27>(char const (&) [27])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<55>(char const (&) [55])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<33>(char const (&) [33])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<73>(char const (&) [73])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<42>(char const (&) [42])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<21>(char const (&) [21])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<6>(char16_t const (&) [6])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<10>(char16_t const (&) [10])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<35>(char const (&) [35])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<26>(char16_t const (&) [26])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<38>(char const (&) [38])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<40>(char const (&) [40])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<29>(char const (&) [29])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<95>(char const (&) [95])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<210>(char const (&) [210])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<3>(char16_t const (&) [3])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<70>(char const (&) [70])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<38>(char16_t const (&) [38])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<55>(char16_t const (&) [55])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<52>(char16_t const (&) [52])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<68>(char16_t const (&) [68])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<19>(char16_t const (&) [19])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<60>(char16_t const (&) [60])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<56>(char16_t const (&) [56])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<57>(char16_t const (&) [57])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<30>(char16_t const (&) [30])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<58>(char16_t const (&) [58])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<35>(char16_t const (&) [35])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<1>(char const (&) [1])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<1>(char16_t const (&) [1])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<89>(char const (&) [89])
Unexecuted instantiation: void nsTSubstring<char>::AppendLiteral<59>(char const (&) [59])
657
658
  template<int N>
659
  void AppendLiteral(const char_type (&aStr)[N], const fallible_t& aFallible)
660
  {
661
    // The case where base_string_type::mLength is zero is intentionally
662
    // left unoptimized (could be optimized as call to AssignLiteral),
663
    // because it's rare/nonexistent. If you add that optimization,
664
    // please be sure to also check that
665
    // !(base_string_type::mDataFlags & DataFlags::REFCOUNTED)
666
    // to avoid undoing the effects of SetCapacity().
667
    return Append(aStr, N - 1, aFallible);
668
  }
669
670
  // Only enable for T = char16_t
671
  //
672
  // Appends an 8-bit literal string ("" literal) to a 16-bit string by
673
  // expanding it. The literal must only contain ASCII.
674
  //
675
  // Using u"" literals with 16-bit strings is generally preferred.
676
  template <int N, typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
677
  void AppendLiteral(const incompatible_char_type (&aStr)[N])
678
8.72k
  {
679
8.72k
    AppendASCII(aStr, N - 1);
680
8.72k
  }
void nsTSubstring<char16_t>::AppendLiteral<3, char16_t, void>(char const (&) [3])
Line
Count
Source
678
3
  {
679
3
    AppendASCII(aStr, N - 1);
680
3
  }
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<5, char16_t, void>(char const (&) [5])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<6, char16_t, void>(char const (&) [6])
void nsTSubstring<char16_t>::AppendLiteral<7, char16_t, void>(char const (&) [7])
Line
Count
Source
678
25
  {
679
25
    AppendASCII(aStr, N - 1);
680
25
  }
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<8, char16_t, void>(char const (&) [8])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<9, char16_t, void>(char const (&) [9])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<12, char16_t, void>(char const (&) [12])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<28, char16_t, void>(char const (&) [28])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<27, char16_t, void>(char const (&) [27])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<10, char16_t, void>(char const (&) [10])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<14, char16_t, void>(char const (&) [14])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<15, char16_t, void>(char const (&) [15])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<39, char16_t, void>(char const (&) [39])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<102, char16_t, void>(char const (&) [102])
void nsTSubstring<char16_t>::AppendLiteral<4, char16_t, void>(char const (&) [4])
Line
Count
Source
678
796
  {
679
796
    AppendASCII(aStr, N - 1);
680
796
  }
void nsTSubstring<char16_t>::AppendLiteral<2, char16_t, void>(char const (&) [2])
Line
Count
Source
678
7.89k
  {
679
7.89k
    AppendASCII(aStr, N - 1);
680
7.89k
  }
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<21, char16_t, void>(char const (&) [21])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<251, char16_t, void>(char const (&) [251])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<61, char16_t, void>(char const (&) [61])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<25, char16_t, void>(char const (&) [25])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<11, char16_t, void>(char const (&) [11])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<63, char16_t, void>(char const (&) [63])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<26, char16_t, void>(char const (&) [26])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<29, char16_t, void>(char const (&) [29])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<31, char16_t, void>(char const (&) [31])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<17, char16_t, void>(char const (&) [17])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<16, char16_t, void>(char const (&) [16])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<18, char16_t, void>(char const (&) [18])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<32, char16_t, void>(char const (&) [32])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<64, char16_t, void>(char const (&) [64])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<37, char16_t, void>(char const (&) [37])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<33, char16_t, void>(char const (&) [33])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<44, char16_t, void>(char const (&) [44])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<43, char16_t, void>(char const (&) [43])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<42, char16_t, void>(char const (&) [42])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<59, char16_t, void>(char const (&) [59])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<13, char16_t, void>(char const (&) [13])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<85, char16_t, void>(char const (&) [85])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<35, char16_t, void>(char const (&) [35])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<75, char16_t, void>(char const (&) [75])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<23, char16_t, void>(char const (&) [23])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<22, char16_t, void>(char const (&) [22])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<34, char16_t, void>(char const (&) [34])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<41, char16_t, void>(char const (&) [41])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<36, char16_t, void>(char const (&) [36])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<19, char16_t, void>(char const (&) [19])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<55, char16_t, void>(char const (&) [55])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<60, char16_t, void>(char const (&) [60])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<73, char16_t, void>(char const (&) [73])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<146, char16_t, void>(char const (&) [146])
Unexecuted instantiation: void nsTSubstring<char16_t>::AppendLiteral<78, char16_t, void>(char const (&) [78])
681
682
  // Only enable for T = char16_t
683
  template <int N, typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
684
  MOZ_MUST_USE bool
685
  AppendLiteral(const incompatible_char_type (&aStr)[N], const fallible_t& aFallible)
686
0
  {
687
0
    return AppendASCII(aStr, N - 1, aFallible);
688
0
  }
Unexecuted instantiation: bool nsTSubstring<char16_t>::AppendLiteral<3, char16_t, void>(char const (&) [3], std::nothrow_t const&)
Unexecuted instantiation: bool nsTSubstring<char16_t>::AppendLiteral<6, char16_t, void>(char const (&) [6], std::nothrow_t const&)
Unexecuted instantiation: bool nsTSubstring<char16_t>::AppendLiteral<2, char16_t, void>(char const (&) [2], std::nothrow_t const&)
689
690
  /**
691
   * Append a formatted string to the current string. Uses the
692
   * standard printf format codes.  This uses NSPR formatting, which will be
693
   * locale-aware for floating-point values.  You probably don't want to use
694
   * this with floating-point values as a result.
695
   */
696
  void AppendPrintf(const char* aFormat, ...) MOZ_FORMAT_PRINTF(2, 3);
697
  void AppendPrintf(const char* aFormat, va_list aAp) MOZ_FORMAT_PRINTF(2, 0);
698
  void AppendInt(int32_t aInteger)
699
  {
700
    AppendPrintf("%" PRId32, aInteger);
701
  }
702
  void AppendInt(int32_t aInteger, int aRadix)
703
  {
704
    if (aRadix == 10) {
705
      AppendPrintf("%" PRId32, aInteger);
706
    } else {
707
      AppendPrintf(aRadix == 8 ? "%" PRIo32 : "%" PRIx32,
708
                   static_cast<uint32_t>(aInteger));
709
    }
710
  }
711
  void AppendInt(uint32_t aInteger)
712
  {
713
    AppendPrintf("%" PRIu32, aInteger);
714
  }
715
  void AppendInt(uint32_t aInteger, int aRadix)
716
  {
717
    AppendPrintf(aRadix == 10 ? "%" PRIu32 : aRadix == 8 ? "%" PRIo32 : "%" PRIx32,
718
                 aInteger);
719
  }
720
  void AppendInt(int64_t aInteger)
721
  {
722
    AppendPrintf("%" PRId64, aInteger);
723
  }
724
  void AppendInt(int64_t aInteger, int aRadix)
725
  {
726
    if (aRadix == 10) {
727
      AppendPrintf("%" PRId64, aInteger);
728
    } else {
729
      AppendPrintf(aRadix == 8 ? "%" PRIo64 : "%" PRIx64,
730
                   static_cast<uint64_t>(aInteger));
731
    }
732
  }
733
  void AppendInt(uint64_t aInteger)
734
0
  {
735
0
    AppendPrintf("%" PRIu64, aInteger);
736
0
  }
737
  void AppendInt(uint64_t aInteger, int aRadix)
738
0
  {
739
0
    AppendPrintf(aRadix == 10 ? "%" PRIu64 : aRadix == 8 ? "%" PRIo64 : "%" PRIx64,
740
0
                 aInteger);
741
0
  }
742
743
  /**
744
   * Append the given float to this string
745
   */
746
  void NS_FASTCALL AppendFloat(float aFloat);
747
  void NS_FASTCALL AppendFloat(double aFloat);
748
749
  self_type& operator+=(char_type aChar)
750
  {
751
    Append(aChar);
752
    return *this;
753
  }
754
  self_type& operator+=(const char_type* aData)
755
  {
756
    Append(aData);
757
    return *this;
758
  }
759
#if defined(MOZ_USE_CHAR16_WRAPPER)
760
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
761
  self_type& operator+=(char16ptr_t aData)
762
  {
763
    Append(aData);
764
    return *this;
765
  }
766
#endif
767
  self_type& operator+=(const self_type& aStr)
768
  {
769
    Append(aStr);
770
    return *this;
771
  }
772
  self_type& operator+=(const substring_tuple_type& aTuple)
773
  {
774
    Append(aTuple);
775
    return *this;
776
  }
777
778
  void Insert(char_type aChar, index_type aPos)
779
  {
780
    Replace(aPos, 0, aChar);
781
  }
782
  void Insert(const char_type* aData, index_type aPos,
783
              size_type aLength = size_type(-1))
784
  {
785
    Replace(aPos, 0, aData, aLength);
786
  }
787
#if defined(MOZ_USE_CHAR16_WRAPPER)
788
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
789
  void Insert(char16ptr_t aData, index_type aPos,
790
              size_type aLength = size_type(-1))
791
  {
792
    Insert(static_cast<const char16_t*>(aData), aPos, aLength);
793
  }
794
#endif
795
  void Insert(const self_type& aStr, index_type aPos)
796
  {
797
    Replace(aPos, 0, aStr);
798
  }
799
  void Insert(const substring_tuple_type& aTuple, index_type aPos)
800
  {
801
    Replace(aPos, 0, aTuple);
802
  }
803
804
  // InsertLiteral must ONLY be applied to an actual literal string.
805
  // Do not attempt to use it with a regular char* pointer, or with a char
806
  // array variable. Use Insert for those.
807
  template<int N>
808
  void InsertLiteral(const char_type (&aStr)[N], index_type aPos)
809
4.43k
  {
810
4.43k
    ReplaceLiteral(aPos, 0, aStr, N - 1);
811
4.43k
  }
void nsTSubstring<char>::InsertLiteral<5>(char const (&) [5], unsigned int)
Line
Count
Source
809
335
  {
810
335
    ReplaceLiteral(aPos, 0, aStr, N - 1);
811
335
  }
Unexecuted instantiation: void nsTSubstring<char16_t>::InsertLiteral<8>(char16_t const (&) [8], unsigned int)
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<8>(char const (&) [8], unsigned int)
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<2>(char const (&) [2], unsigned int)
Unexecuted instantiation: void nsTSubstring<char16_t>::InsertLiteral<5>(char16_t const (&) [5], unsigned int)
Unexecuted instantiation: void nsTSubstring<char16_t>::InsertLiteral<6>(char16_t const (&) [6], unsigned int)
Unexecuted instantiation: void nsTSubstring<char16_t>::InsertLiteral<7>(char16_t const (&) [7], unsigned int)
void nsTSubstring<char>::InsertLiteral<44>(char const (&) [44], unsigned int)
Line
Count
Source
809
4.09k
  {
810
4.09k
    ReplaceLiteral(aPos, 0, aStr, N - 1);
811
4.09k
  }
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<16>(char const (&) [16], unsigned int)
void nsTSubstring<char>::InsertLiteral<6>(char const (&) [6], unsigned int)
Line
Count
Source
809
5
  {
810
5
    ReplaceLiteral(aPos, 0, aStr, N - 1);
811
5
  }
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<7>(char const (&) [7], unsigned int)
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<24>(char const (&) [24], unsigned int)
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<17>(char const (&) [17], unsigned int)
Unexecuted instantiation: void nsTSubstring<char16_t>::InsertLiteral<2>(char16_t const (&) [2], unsigned int)
Unexecuted instantiation: void nsTSubstring<char>::InsertLiteral<30>(char const (&) [30], unsigned int)
812
813
  void Cut(index_type aCutStart, size_type aCutLength)
814
  {
815
    Replace(aCutStart, aCutLength, char_traits::sEmptyBuffer, 0);
816
  }
817
818
  nsTSubstringSplitter<T> Split(const char_type aChar) const;
819
820
  /**
821
   * buffer sizing
822
   */
823
824
  /**
825
   * Attempts to set the capacity to the given size in number of
826
   * code units without affecting the length of the string in
827
   * order to avoid reallocation during a subsequent sequence of
828
   * appends.
829
   *
830
   * This method is appropriate to use before a sequence of multiple
831
   * operations from the following list (without operations that are
832
   * not on the list between the SetCapacity() call and operations
833
   * from the list):
834
   *
835
   * Append()
836
   * AppendASCII()
837
   * AppendLiteral() (except if the string is empty: bug 1487606)
838
   * AppendPrintf()
839
   * AppendInt()
840
   * AppendFloat()
841
   * LossyAppendUTF16toASCII()
842
   * AppendASCIItoUTF16()
843
   *
844
   * DO NOT call SetCapacity() if the subsequent operations on the
845
   * string do not meet the criteria above. Operations that undo
846
   * the benefits of SetCapacity() include but are not limited to:
847
   *
848
   * SetLength()
849
   * Truncate()
850
   * Assign()
851
   * AssignLiteral()
852
   * Adopt()
853
   * CopyASCIItoUTF16()
854
   * LossyCopyUTF16toASCII()
855
   * AppendUTF16toUTF8()
856
   * AppendUTF8toUTF16()
857
   * CopyUTF16toUTF8()
858
   * CopyUTF8toUTF16()
859
   *
860
   * If your string is an nsAuto[C]String and you are calling
861
   * SetCapacity() with a constant N, please instead declare the
862
   * string as nsAuto[C]StringN<N+1> without calling SetCapacity().
863
   *
864
   * There is no need to include room for the null terminator: it is
865
   * the job of the string class.
866
   *
867
   * Note: Calling SetCapacity() does not give you permission to
868
   * use the pointer obtained from BeginWriting() to write
869
   * past the current length (as returned by Length()) of the
870
   * string. Please use either BulkWrite() or SetLength()
871
   * instead.
872
   *
873
   * Note: SetCapacity() won't make the string shorter if
874
   * called with an argument smaller than the length of the
875
   * string.
876
   *
877
   * Note: You must not use previously obtained iterators
878
   * or spans after calling SetCapacity().
879
   */
880
  void NS_FASTCALL SetCapacity(size_type aNewCapacity);
881
  MOZ_MUST_USE bool NS_FASTCALL SetCapacity(size_type aNewCapacity,
882
                                            const fallible_t&);
883
884
  /**
885
   * Changes the logical length of the string, potentially
886
   * allocating a differently-sized buffer for the string.
887
   *
888
   * When making the string shorter, this method never
889
   * reports allocation failure.
890
   *
891
   * Exposes uninitialized memory if the string got longer.
892
   *
893
   * If called with the argument 0, releases the
894
   * heap-allocated buffer, if any. (But the no-argument
895
   * overload of Truncate() is a more idiomatic and efficient
896
   * option than SetLength(0).)
897
   *
898
   * Note: You must not use previously obtained iterators
899
   * or spans after calling SetLength().
900
   */
901
  void NS_FASTCALL SetLength(size_type aNewLength);
902
  MOZ_MUST_USE bool NS_FASTCALL SetLength(size_type aNewLength,
903
                                          const fallible_t&);
904
905
  /**
906
   * Like SetLength() but asserts in that the string
907
   * doesn't become longer. Never fails, so doesn't need a
908
   * fallible variant.
909
   *
910
   * Note: You must not use previously obtained iterators
911
   * or spans after calling Truncate().
912
   */
913
  void Truncate(size_type aNewLength)
914
1.09M
  {
915
1.09M
    MOZ_RELEASE_ASSERT(aNewLength <= base_string_type::mLength,
916
1.09M
                       "Truncate cannot make string longer");
917
1.09M
    mozilla::DebugOnly<bool> success = SetLength(aNewLength, mozilla::fallible);
918
1.09M
    MOZ_ASSERT(success);
919
1.09M
  }
920
921
  /**
922
   * A more efficient overload for Truncate(0). Releases the
923
   * heap-allocated buffer if any.
924
   */
925
  void Truncate();
926
927
  /**
928
   * buffer access
929
   */
930
931
932
  /**
933
   * Get a const pointer to the string's internal buffer.  The caller
934
   * MUST NOT modify the characters at the returned address.
935
   *
936
   * @returns The length of the buffer in characters.
937
   */
938
  inline size_type GetData(const char_type** aData) const
939
  {
940
    *aData = base_string_type::mData;
941
    return base_string_type::mLength;
942
  }
943
944
  /**
945
   * Get a pointer to the string's internal buffer, optionally resizing
946
   * the buffer first.  If size_type(-1) is passed for newLen, then the
947
   * current length of the string is used.  The caller MAY modify the
948
   * characters at the returned address (up to but not exceeding the
949
   * length of the string).
950
   *
951
   * @returns The length of the buffer in characters or 0 if unable to
952
   * satisfy the request due to low-memory conditions.
953
   */
954
  size_type GetMutableData(char_type** aData, size_type aNewLen = size_type(-1))
955
  {
956
    if (!EnsureMutable(aNewLen)) {
957
      AllocFailed(aNewLen == size_type(-1) ? base_string_type::mLength : aNewLen);
958
    }
959
960
    *aData = base_string_type::mData;
961
    return base_string_type::mLength;
962
  }
963
964
  size_type GetMutableData(char_type** aData, size_type aNewLen, const fallible_t&)
965
  {
966
    if (!EnsureMutable(aNewLen)) {
967
      *aData = nullptr;
968
      return 0;
969
    }
970
971
    *aData = base_string_type::mData;
972
    return base_string_type::mLength;
973
  }
974
975
#if defined(MOZ_USE_CHAR16_WRAPPER)
976
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
977
  size_type GetMutableData(wchar_t** aData, size_type aNewLen = size_type(-1))
978
  {
979
    return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen);
980
  }
981
982
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
983
  size_type GetMutableData(wchar_t** aData, size_type aNewLen,
984
                           const fallible_t& aFallible)
985
  {
986
    return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen,
987
                          aFallible);
988
  }
989
#endif
990
991
  /**
992
   * Span integration
993
   */
994
995
  operator mozilla::Span<char_type>()
996
  {
997
    return mozilla::MakeSpan(BeginWriting(), base_string_type::Length());
998
  }
999
1000
  operator mozilla::Span<const char_type>() const
1001
3.19M
  {
1002
3.19M
    return mozilla::MakeSpan(base_string_type::BeginReading(), base_string_type::Length());
1003
3.19M
  }
1004
1005
  void Append(mozilla::Span<const char_type> aSpan)
1006
  {
1007
    auto len = aSpan.Length();
1008
    MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value);
1009
    Append(aSpan.Elements(), len);
1010
  }
1011
1012
  MOZ_MUST_USE bool Append(mozilla::Span<const char_type> aSpan,
1013
                           const fallible_t& aFallible)
1014
  {
1015
    auto len = aSpan.Length();
1016
    if (len > mozilla::MaxValue<size_type>::value) {
1017
      return false;
1018
    }
1019
    return Append(aSpan.Elements(), len, aFallible);
1020
  }
1021
1022
  template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
1023
  operator mozilla::Span<uint8_t>()
1024
0
  {
1025
0
    return mozilla::MakeSpan(reinterpret_cast<uint8_t*>(BeginWriting()),
1026
0
                             base_string_type::Length());
1027
0
  }
1028
1029
  template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
1030
  operator mozilla::Span<const uint8_t>() const
1031
0
  {
1032
0
    return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(base_string_type::BeginReading()),
1033
0
                             base_string_type::Length());
1034
0
  }
1035
1036
  template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
1037
  void Append(mozilla::Span<const uint8_t> aSpan)
1038
0
  {
1039
0
    auto len = aSpan.Length();
1040
0
    MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value);
1041
0
    Append(reinterpret_cast<const char*>(aSpan.Elements()), len);
1042
0
  }
1043
1044
  template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
1045
  MOZ_MUST_USE bool Append(mozilla::Span<const uint8_t> aSpan,
1046
                           const fallible_t& aFallible)
1047
  {
1048
    auto len = aSpan.Length();
1049
    if (len > mozilla::MaxValue<size_type>::value) {
1050
      return false;
1051
    }
1052
    return Append(
1053
      reinterpret_cast<const char*>(aSpan.Elements()), len, aFallible);
1054
  }
1055
1056
  /**
1057
   * string data is never null, but can be marked void.  if true, the
1058
   * string will be truncated.  @see nsTSubstring::IsVoid
1059
   */
1060
1061
  void NS_FASTCALL SetIsVoid(bool);
1062
1063
  /**
1064
   *  This method is used to remove all occurrences of aChar from this
1065
   * string.
1066
   *
1067
   *  @param  aChar -- char to be stripped
1068
   */
1069
1070
  void StripChar(char_type aChar);
1071
1072
  /**
1073
   *  This method is used to remove all occurrences of aChars from this
1074
   * string.
1075
   *
1076
   *  @param  aChars -- chars to be stripped
1077
   */
1078
1079
  void StripChars(const char_type* aChars);
1080
1081
  /**
1082
   * This method is used to remove all occurrences of some characters this
1083
   * from this string.  The characters removed have the corresponding
1084
   * entries in the bool array set to true; we retain all characters
1085
   * with code beyond 127.
1086
   * THE CALLER IS RESPONSIBLE for making sure the complete boolean
1087
   * array, 128 entries, is properly initialized.
1088
   *
1089
   * See also: ASCIIMask class.
1090
   *
1091
   *  @param  aToStrip -- Array where each entry is true if the
1092
   *          corresponding ASCII character is to be stripped.  All
1093
   *          characters beyond code 127 are retained.  Note that this
1094
   *          parameter is of ASCIIMaskArray type, but we expand the typedef
1095
   *          to avoid having to include nsASCIIMask.h in this include file
1096
   *          as it brings other includes.
1097
   */
1098
  void StripTaggedASCII(const std::array<bool, 128>& aToStrip);
1099
1100
  /**
1101
   * A shortcut to strip \r and \n.
1102
   */
1103
  void StripCRLF();
1104
1105
  /**
1106
   * If the string uses a shared buffer, this method
1107
   * clears the pointer without releasing the buffer.
1108
   */
1109
  void ForgetSharedBuffer()
1110
  {
1111
    if (base_string_type::mDataFlags & DataFlags::REFCOUNTED) {
1112
      SetToEmptyBuffer();
1113
    }
1114
  }
1115
1116
protected:
1117
  void AssertValid()
1118
453M
  {
1119
453M
    MOZ_ASSERT(!(this->mClassFlags & ClassFlags::NULL_TERMINATED) ||
1120
453M
               (this->mDataFlags & DataFlags::TERMINATED),
1121
453M
               "String classes whose static type guarantees a null-terminated "
1122
453M
               "buffer must not be assigned a non-null-terminated buffer.");
1123
453M
  }
nsTSubstring<char>::AssertValid()
Line
Count
Source
1118
351M
  {
1119
351M
    MOZ_ASSERT(!(this->mClassFlags & ClassFlags::NULL_TERMINATED) ||
1120
351M
               (this->mDataFlags & DataFlags::TERMINATED),
1121
351M
               "String classes whose static type guarantees a null-terminated "
1122
351M
               "buffer must not be assigned a non-null-terminated buffer.");
1123
351M
  }
nsTSubstring<char16_t>::AssertValid()
Line
Count
Source
1118
101M
  {
1119
101M
    MOZ_ASSERT(!(this->mClassFlags & ClassFlags::NULL_TERMINATED) ||
1120
101M
               (this->mDataFlags & DataFlags::TERMINATED),
1121
101M
               "String classes whose static type guarantees a null-terminated "
1122
101M
               "buffer must not be assigned a non-null-terminated buffer.");
1123
101M
  }
1124
1125
public:
1126
1127
  /**
1128
   * this is public to support automatic conversion of tuple to string
1129
   * base type, which helps avoid converting to nsTAString.
1130
   */
1131
  MOZ_IMPLICIT nsTSubstring(const substring_tuple_type& aTuple)
1132
    : base_string_type(nullptr, 0, DataFlags(0), ClassFlags(0))
1133
  {
1134
    AssertValid();
1135
    Assign(aTuple);
1136
  }
1137
1138
  size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
1139
  const;
1140
  size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
1141
  const;
1142
1143
  /**
1144
   * WARNING: Only use these functions if you really know what you are
1145
   * doing, because they can easily lead to double-counting strings.  If
1146
   * you do use them, please explain clearly in a comment why it's safe
1147
   * and won't lead to double-counting.
1148
   */
1149
  size_t SizeOfExcludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
1150
  const;
1151
  size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
1152
  const;
1153
1154
  template<class N>
1155
  void NS_ABORT_OOM(T)
1156
  {
1157
    struct never {}; // a compiler-friendly way to do static_assert(false)
1158
    static_assert(mozilla::IsSame<N, never>::value,
1159
      "In string classes, use AllocFailed to account for sizeof(char_type). "
1160
      "Use the global ::NS_ABORT_OOM if you really have a count of bytes.");
1161
  }
1162
1163
  MOZ_ALWAYS_INLINE void AllocFailed(size_t aLength)
1164
0
  {
1165
0
    ::NS_ABORT_OOM(aLength * sizeof(char_type));
1166
0
  }
1167
1168
protected:
1169
1170
  // default initialization
1171
  nsTSubstring()
1172
    : base_string_type(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
1173
                       ClassFlags(0))
1174
64.7M
  {
1175
64.7M
    AssertValid();
1176
64.7M
  }
1177
1178
  // copy-constructor, constructs as dependent on given object
1179
  // (NOTE: this is for internal use only)
1180
  nsTSubstring(const self_type& aStr)
1181
    : base_string_type(aStr.base_string_type::mData, aStr.base_string_type::mLength,
1182
                       aStr.base_string_type::mDataFlags & (DataFlags::TERMINATED | DataFlags::VOIDED),
1183
                       ClassFlags(0))
1184
  {
1185
    AssertValid();
1186
  }
1187
1188
  // initialization with ClassFlags
1189
  explicit nsTSubstring(ClassFlags aClassFlags)
1190
    : base_string_type(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
1191
                       aClassFlags)
1192
52.9M
  {
1193
52.9M
    AssertValid();
1194
52.9M
  }
1195
1196
 /**
1197
   * allows for direct initialization of a nsTSubstring object.
1198
   */
1199
  nsTSubstring(char_type* aData, size_type aLength,
1200
               DataFlags aDataFlags, ClassFlags aClassFlags)
1201
// XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
1202
#if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
1203
#define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
1204
    ;
1205
#else
1206
#undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
1207
    : base_string_type(aData, aLength, aDataFlags, aClassFlags)
1208
73.1M
  {
1209
73.1M
    AssertValid();
1210
73.1M
    MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");
1211
73.1M
  }
nsTSubstring<char>::nsTSubstring(char*, unsigned int, mozilla::detail::StringDataFlags, mozilla::detail::StringClassFlags)
Line
Count
Source
1208
72.1M
  {
1209
72.1M
    AssertValid();
1210
72.1M
    MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");
1211
72.1M
  }
nsTSubstring<char16_t>::nsTSubstring(char16_t*, unsigned int, mozilla::detail::StringDataFlags, mozilla::detail::StringClassFlags)
Line
Count
Source
1208
975k
  {
1209
975k
    AssertValid();
1210
975k
    MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");
1211
975k
  }
1212
#endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */
1213
1214
  void SetToEmptyBuffer()
1215
  {
1216
    base_string_type::mData = char_traits::sEmptyBuffer;
1217
    base_string_type::mLength = 0;
1218
    base_string_type::mDataFlags = DataFlags::TERMINATED;
1219
    AssertValid();
1220
  }
1221
1222
  void SetData(char_type* aData, size_type aLength, DataFlags aDataFlags)
1223
  {
1224
    base_string_type::mData = aData;
1225
    base_string_type::mLength = aLength;
1226
    base_string_type::mDataFlags = aDataFlags;
1227
    AssertValid();
1228
  }
1229
1230
  /**
1231
   * this function releases mData and does not change the value of
1232
   * any of its member variables.  in other words, this function acts
1233
   * like a destructor.
1234
   */
1235
  void NS_FASTCALL Finalize();
1236
1237
public:
1238
1239
  /**
1240
   * Starts a low-level write transaction to the string.
1241
   *
1242
   * Prepares the string for mutation such that the capacity
1243
   * of the string is at least aCapacity. The returned handle
1244
   * exposes the actual, potentially larger, capacity.
1245
   *
1246
   * If meeting the capacity or mutability requirement requires
1247
   * reallocation, aPrefixToPreserve code units are copied from the
1248
   * start of the old buffer to the start of the new buffer.
1249
   * aPrefixToPreserve must not be greater than the string's current
1250
   * length or greater than aCapacity.
1251
   *
1252
   * aAllowShrinking indicates whether an allocation may be
1253
   * performed when the string is already mutable and the requested
1254
   * capacity is smaller than the current capacity.
1255
   *
1256
   * aRv takes a reference to an nsresult that will be set to
1257
   * NS_OK on success or to NS_ERROR_OUT_OF_MEMORY on failure,
1258
   * because mozilla::Result cannot wrap move-only types at
1259
   * this time.
1260
   *
1261
   * If this method returns successfully, you must not access
1262
   * the string except through the returned BulkWriteHandle
1263
   * until either the BulkWriteHandle goes out of scope or
1264
   * you call Finish() on the BulkWriteHandle.
1265
   *
1266
   * Compared to SetLength() and BeginWriting(), this more
1267
   * complex API accomplishes two things:
1268
   *  1) It exposes the actual capacity which may be larger
1269
   *     than the requested capacity, which is useful in some
1270
   *     multi-step write operations that don't allocate for
1271
   *     the worst case up front.
1272
   *  2) It writes the zero terminator after the string
1273
   *     content has been written, which results in a
1274
   *     cache-friendly linear write pattern.
1275
   */
1276
  mozilla::BulkWriteHandle<T>
1277
  NS_FASTCALL BulkWrite(size_type aCapacity,
1278
                        size_type aPrefixToPreserve,
1279
                        bool aAllowShrinking,
1280
                        nsresult& aRv);
1281
1282
  /**
1283
   * THIS IS NOT REALLY A PUBLIC METHOD! DO NOT CALL FROM OUTSIDE
1284
   * THE STRING IMPLEMENTATION. (It's public only because friend
1285
   * declarations don't allow extern or static and this needs to
1286
   * be called from Rust FFI glue.)
1287
   *
1288
   * Prepares mData to be mutated such that the capacity of the string
1289
   * (not counting the zero-terminator) is at least aCapacity.
1290
   * Returns the actual capacity, which may be larger than what was
1291
   * requested or Err(NS_ERROR_OUT_OF_MEMORY) on allocation failure.
1292
   *
1293
   * mLength is ignored by this method. If the buffer is reallocated,
1294
   * aUnitsToPreserve specifies how many code units to copy over to
1295
   * the new buffer. The old buffer is freed if applicable.
1296
   *
1297
   * Unless the return value is Err(NS_ERROR_OUT_OF_MEMORY) to signal
1298
   * failure or 0 to signal that the string has been set to
1299
   * the special empty state, this method leaves the string in an
1300
   * invalid state! The caller is responsible for calling
1301
   * FinishBulkWrite() (or in Rust calling
1302
   * nsA[C]StringBulkWriteHandle::finish()), which put the string
1303
   * into a valid state by setting mLength and zero-terminating.
1304
   * This method sets the flag to claim that the string is
1305
   * zero-terminated before it actually is.
1306
   *
1307
   * Once this method has been called and before FinishBulkWrite()
1308
   * has been called, only accessing mData or calling this method
1309
   * again are valid operations. Do not call any other methods or
1310
   * access other fields between calling this method and
1311
   * FinishBulkWrite().
1312
   *
1313
   * @param aCapacity The requested capacity. The return value
1314
   *                  will be greater than or equal to this value.
1315
   * @param aPrefixToPreserve The number of code units at the start
1316
   *                          of the old buffer to copy into the
1317
   *                          new buffer.
1318
   * @parem aAllowShrinking If true, an allocation may be performed
1319
   *                        if the requested capacity is smaller
1320
   *                        than the current capacity.
1321
   * @param aSuffixLength The length, in code units, of a suffix
1322
   *                      to move.
1323
   * @param aOldSuffixStart The old start index of the suffix to
1324
   *                        move.
1325
   * @param aNewSuffixStart The new start index of the suffix to
1326
   *                        move.
1327
   *
1328
   */
1329
  mozilla::Result<uint32_t, nsresult>
1330
  NS_FASTCALL StartBulkWriteImpl(size_type aCapacity,
1331
                                 size_type aPrefixToPreserve = 0,
1332
                                 bool aAllowShrinking = true,
1333
                                 size_type aSuffixLength = 0,
1334
                                 size_type aOldSuffixStart = 0,
1335
                                 size_type aNewSuffixStart = 0);
1336
1337
private:
1338
  /**
1339
   * Do not call this except from within FinishBulkWriteImpl() and
1340
   * SetCapacity().
1341
   */
1342
  MOZ_ALWAYS_INLINE void NS_FASTCALL FinishBulkWriteImplImpl(size_type aLength)
1343
  {
1344
    base_string_type::mData[aLength] = char_type(0);
1345
    base_string_type::mLength = aLength;
1346
#ifdef DEBUG
1347
    // ifdefed in order to avoid the call to Capacity() in non-debug
1348
    // builds.
1349
    //
1350
    // Our string is mutable, so Capacity() doesn't return zero.
1351
    // Capacity() doesn't include the space for the zero terminator,
1352
    // but we want to unitialize that slot, too. Since we start
1353
    // counting after the zero terminator the we just wrote above,
1354
    // we end up overwriting the space for terminator not reflected
1355
    // in the capacity number.
1356
    char_traits::uninitialize(
1357
      base_string_type::mData + aLength + 1,
1358
      XPCOM_MIN(size_t(Capacity() - aLength), kNsStringBufferMaxPoison));
1359
#endif
1360
  }
1361
1362
protected:
1363
  /**
1364
   * Restores the string to a valid state after a call to StartBulkWrite()
1365
   * that returned a non-error result. The argument to this method
1366
   * must be less than or equal to the value returned by the most recent
1367
   * StartBulkWrite() call.
1368
   */
1369
  void NS_FASTCALL FinishBulkWriteImpl(size_type aLength);
1370
1371
  /**
1372
   * this function prepares a section of mData to be modified.  if
1373
   * necessary, this function will reallocate mData and possibly move
1374
   * existing data to open up the specified section.
1375
   *
1376
   * @param aCutStart    specifies the starting offset of the section
1377
   * @param aCutLength   specifies the length of the section to be replaced
1378
   * @param aNewLength   specifies the length of the new section
1379
   *
1380
   * for example, suppose mData contains the string "abcdef" then
1381
   *
1382
   *   ReplacePrep(2, 3, 4);
1383
   *
1384
   * would cause mData to look like "ab____f" where the characters
1385
   * indicated by '_' have an unspecified value and can be freely
1386
   * modified.  this function will null-terminate mData upon return.
1387
   *
1388
   * this function returns false if is unable to allocate sufficient
1389
   * memory.
1390
   */
1391
  MOZ_MUST_USE bool ReplacePrep(index_type aCutStart,
1392
                                size_type aCutLength,
1393
                                size_type aNewLength);
1394
1395
  MOZ_MUST_USE bool NS_FASTCALL ReplacePrepInternal(
1396
    index_type aCutStart,
1397
    size_type aCutLength,
1398
    size_type aNewFragLength,
1399
    size_type aNewTotalLength);
1400
1401
  /**
1402
   * returns the number of writable storage units starting at mData.
1403
   * the value does not include space for the null-terminator character.
1404
   *
1405
   * NOTE: this function returns 0 if mData is immutable (or the buffer
1406
   *       is 0-sized).
1407
   */
1408
  size_type NS_FASTCALL Capacity() const;
1409
1410
  /**
1411
   * this helper function can be called prior to directly manipulating
1412
   * the contents of mData.  see, for example, BeginWriting.
1413
   */
1414
  MOZ_MUST_USE bool NS_FASTCALL EnsureMutable(
1415
    size_type aNewLen = size_type(-1));
1416
1417
  /**
1418
   * Checks if the given capacity is valid for this string type.
1419
   */
1420
99.2M
  static MOZ_MUST_USE bool CheckCapacity(size_type aCapacity) {
1421
99.2M
    if (aCapacity > kMaxCapacity) {
1422
0
      // Also assert for |aCapacity| equal to |size_type(-1)|, since we used to
1423
0
      // use that value to flag immutability.
1424
0
      NS_ASSERTION(aCapacity != size_type(-1), "Bogus capacity");
1425
0
      return false;
1426
0
    }
1427
99.2M
1428
99.2M
    return true;
1429
99.2M
  }
nsTSubstring<char>::CheckCapacity(unsigned int)
Line
Count
Source
1420
85.8M
  static MOZ_MUST_USE bool CheckCapacity(size_type aCapacity) {
1421
85.8M
    if (aCapacity > kMaxCapacity) {
1422
0
      // Also assert for |aCapacity| equal to |size_type(-1)|, since we used to
1423
0
      // use that value to flag immutability.
1424
0
      NS_ASSERTION(aCapacity != size_type(-1), "Bogus capacity");
1425
0
      return false;
1426
0
    }
1427
85.8M
1428
85.8M
    return true;
1429
85.8M
  }
nsTSubstring<char16_t>::CheckCapacity(unsigned int)
Line
Count
Source
1420
13.3M
  static MOZ_MUST_USE bool CheckCapacity(size_type aCapacity) {
1421
13.3M
    if (aCapacity > kMaxCapacity) {
1422
0
      // Also assert for |aCapacity| equal to |size_type(-1)|, since we used to
1423
0
      // use that value to flag immutability.
1424
0
      NS_ASSERTION(aCapacity != size_type(-1), "Bogus capacity");
1425
0
      return false;
1426
0
    }
1427
13.3M
1428
13.3M
    return true;
1429
13.3M
  }
1430
1431
  void NS_FASTCALL ReplaceLiteral(index_type aCutStart, size_type aCutLength,
1432
                                  const char_type* aData, size_type aLength);
1433
1434
  static const size_type kMaxCapacity;
1435
public:
1436
1437
  // NOTE: this method is declared public _only_ for convenience for
1438
  // callers who don't have access to the original nsLiteralString_CharT.
1439
  void NS_FASTCALL AssignLiteral(const char_type* aData, size_type aLength);
1440
};
1441
1442
extern template class nsTSubstring<char>;
1443
extern template class nsTSubstring<char16_t>;
1444
1445
static_assert(sizeof(nsTSubstring<char>) ==
1446
              sizeof(mozilla::detail::nsTStringRepr<char>),
1447
              "Don't add new data fields to nsTSubstring_CharT. "
1448
              "Add to nsTStringRepr<T> instead.");
1449
1450
1451
// You should not need to instantiate this class directly.
1452
// Use nsTSubstring::Split instead.
1453
template <typename T>
1454
class nsTSubstringSplitter
1455
{
1456
  typedef typename nsTSubstring<T>::size_type size_type;
1457
  typedef typename nsTSubstring<T>::char_type char_type;
1458
1459
  class nsTSubstringSplit_Iter
1460
  {
1461
  public:
1462
    nsTSubstringSplit_Iter(const nsTSubstringSplitter<T>& aObj,
1463
                           size_type aPos)
1464
      : mObj(aObj)
1465
      , mPos(aPos)
1466
48
    {
1467
48
    }
1468
1469
    bool operator!=(const nsTSubstringSplit_Iter& other) const
1470
60
    {
1471
60
      return mPos != other.mPos;
1472
60
    }
1473
1474
    const nsTDependentSubstring<T>& operator*() const;
1475
1476
    const nsTSubstringSplit_Iter& operator++()
1477
36
    {
1478
36
      ++mPos;
1479
36
      return *this;
1480
36
    }
1481
1482
  private:
1483
    const nsTSubstringSplitter<T>& mObj;
1484
    size_type mPos;
1485
  };
1486
1487
private:
1488
  const nsTSubstring<T>* const mStr;
1489
  mozilla::UniquePtr<nsTDependentSubstring<T>[]> mArray;
1490
  size_type mArraySize;
1491
  const char_type mDelim;
1492
1493
public:
1494
  nsTSubstringSplitter(const nsTSubstring<T>* aStr, char_type aDelim);
1495
1496
  nsTSubstringSplit_Iter begin() const
1497
24
  {
1498
24
    return nsTSubstringSplit_Iter(*this, 0);
1499
24
  }
1500
1501
  nsTSubstringSplit_Iter end() const
1502
24
  {
1503
24
    return nsTSubstringSplit_Iter(*this, mArraySize);
1504
24
  }
1505
1506
  const nsTDependentSubstring<T>& Get(const size_type index) const
1507
  {
1508
    MOZ_ASSERT(index < mArraySize);
1509
    return mArray[index];
1510
  }
1511
};
1512
1513
extern template class nsTSubstringSplitter<char>;
1514
extern template class nsTSubstringSplitter<char16_t>;
1515
1516
/**
1517
 * Span integration
1518
 */
1519
namespace mozilla {
1520
1521
inline Span<char>
1522
MakeSpan(nsTSubstring<char>& aString)
1523
0
{
1524
0
  return aString;
1525
0
}
1526
1527
inline Span<const char>
1528
MakeSpan(const nsTSubstring<char>& aString)
1529
0
{
1530
0
  return aString;
1531
0
}
1532
1533
inline Span<char16_t>
1534
MakeSpan(nsTSubstring<char16_t>& aString)
1535
0
{
1536
0
  return aString;
1537
0
}
1538
1539
inline Span<const char16_t>
1540
MakeSpan(const nsTSubstring<char16_t>& aString)
1541
0
{
1542
0
  return aString;
1543
0
}
1544
1545
1546
} // namespace mozilla
1547
1548
#endif