Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/string/nsTString.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 nsTString_h
9
#define nsTString_h
10
11
#include "nsTSubstring.h"
12
13
/**
14
 * This is the canonical null-terminated string class.  All subclasses
15
 * promise null-terminated storage.  Instances of this class allocate
16
 * strings on the heap.
17
 *
18
 * NAMES:
19
 *   nsString for wide characters
20
 *   nsCString for narrow characters
21
 *
22
 * This class is also known as nsAFlat[C]String, where "flat" is used
23
 * to denote a null-terminated string.
24
 */
25
template <typename T>
26
class nsTString : public nsTSubstring<T>
27
{
28
public:
29
30
  typedef nsTString<T> self_type;
31
32
#ifdef __clang__
33
  // bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
34
  using typename nsTSubstring<T>::substring_type;
35
#else
36
  // On the other hand msvc chokes on the using statement. It seems others
37
  // don't care either way so we lump them in here.
38
  typedef typename nsTSubstring<T>::substring_type substring_type;
39
#endif
40
41
  typedef typename substring_type::fallible_t fallible_t;
42
43
  typedef typename substring_type::char_type char_type;
44
  typedef typename substring_type::char_traits char_traits;
45
  typedef typename substring_type::incompatible_char_type incompatible_char_type;
46
47
  typedef typename substring_type::substring_tuple_type substring_tuple_type;
48
49
  typedef typename substring_type::const_iterator const_iterator;
50
  typedef typename substring_type::iterator iterator;
51
52
  typedef typename substring_type::comparator_type comparator_type;
53
54
  typedef typename substring_type::const_char_iterator const_char_iterator;
55
56
  typedef typename substring_type::index_type index_type;
57
  typedef typename substring_type::size_type size_type;
58
59
  // These are only for internal use within the string classes:
60
  typedef typename substring_type::DataFlags DataFlags;
61
  typedef typename substring_type::ClassFlags ClassFlags;
62
63
public:
64
65
  /**
66
   * constructors
67
   */
68
69
  nsTString()
70
    : substring_type(ClassFlags::NULL_TERMINATED)
71
1.05M
  {
72
1.05M
  }
73
74
  explicit
75
  nsTString(const char_type* aData, size_type aLength = size_type(-1))
76
    : substring_type(ClassFlags::NULL_TERMINATED)
77
2.54M
  {
78
2.54M
    this->Assign(aData, aLength);
79
2.54M
  }
nsTString<char>::nsTString(char const*, unsigned int)
Line
Count
Source
77
2.54M
  {
78
2.54M
    this->Assign(aData, aLength);
79
2.54M
  }
Unexecuted instantiation: nsTString<char16_t>::nsTString(char16_t const*, unsigned int)
80
81
#if defined(MOZ_USE_CHAR16_WRAPPER)
82
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
83
  explicit
84
  nsTString(char16ptr_t aStr, size_type aLength = size_type(-1))
85
    : substring_type(ClassFlags::NULL_TERMINATED)
86
  {
87
    this->Assign(static_cast<const char16_t*>(aStr), aLength);
88
  }
89
#endif
90
91
  nsTString(const self_type& aStr)
92
    : substring_type(ClassFlags::NULL_TERMINATED)
93
15.0M
  {
94
15.0M
    this->Assign(aStr);
95
15.0M
  }
96
97
  nsTString(self_type&& aStr)
98
    : substring_type(ClassFlags::NULL_TERMINATED)
99
1.12M
  {
100
1.12M
    this->Assign(std::move(aStr));
101
1.12M
  }
nsTString<char>::nsTString(nsTString<char>&&)
Line
Count
Source
99
1.12M
  {
100
1.12M
    this->Assign(std::move(aStr));
101
1.12M
  }
nsTString<char16_t>::nsTString(nsTString<char16_t>&&)
Line
Count
Source
99
24
  {
100
24
    this->Assign(std::move(aStr));
101
24
  }
102
103
  MOZ_IMPLICIT nsTString(const substring_tuple_type& aTuple)
104
    : substring_type(ClassFlags::NULL_TERMINATED)
105
3
  {
106
3
    this->Assign(aTuple);
107
3
  }
nsTString<char>::nsTString(nsTSubstringTuple<char> const&)
Line
Count
Source
105
3
  {
106
3
    this->Assign(aTuple);
107
3
  }
Unexecuted instantiation: nsTString<char16_t>::nsTString(nsTSubstringTuple<char16_t> const&)
108
109
  explicit
110
  nsTString(const substring_type& aReadable)
111
    : substring_type(ClassFlags::NULL_TERMINATED)
112
192k
  {
113
192k
    this->Assign(aReadable);
114
192k
  }
115
116
  explicit
117
  nsTString(substring_type&& aReadable)
118
    : substring_type(ClassFlags::NULL_TERMINATED)
119
0
  {
120
0
    this->Assign(std::move(aReadable));
121
0
  }
Unexecuted instantiation: nsTString<char>::nsTString(nsTSubstring<char>&&)
Unexecuted instantiation: nsTString<char16_t>::nsTString(nsTSubstring<char16_t>&&)
122
123
  // |operator=| does not inherit, so we must define our own
124
  self_type& operator=(char_type aChar)
125
0
  {
126
0
    this->Assign(aChar);
127
0
    return *this;
128
0
  }
Unexecuted instantiation: nsTString<char>::operator=(char)
Unexecuted instantiation: nsTString<char16_t>::operator=(char16_t)
129
  self_type& operator=(const char_type* aData)
130
0
  {
131
0
    this->Assign(aData);
132
0
    return *this;
133
0
  }
134
  self_type& operator=(const self_type& aStr)
135
3.59M
  {
136
3.59M
    this->Assign(aStr);
137
3.59M
    return *this;
138
3.59M
  }
139
  self_type& operator=(self_type&& aStr)
140
3.99k
  {
141
3.99k
    this->Assign(std::move(aStr));
142
3.99k
    return *this;
143
3.99k
  }
nsTString<char>::operator=(nsTString<char>&&)
Line
Count
Source
140
3.99k
  {
141
3.99k
    this->Assign(std::move(aStr));
142
3.99k
    return *this;
143
3.99k
  }
Unexecuted instantiation: nsTString<char16_t>::operator=(nsTString<char16_t>&&)
144
#if defined(MOZ_USE_CHAR16_WRAPPER)
145
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
146
  self_type& operator=(const char16ptr_t aStr)
147
  {
148
    this->Assign(static_cast<const char16_t*>(aStr));
149
    return *this;
150
  }
151
#endif
152
  self_type& operator=(const substring_type& aStr)
153
26.5k
  {
154
26.5k
    this->Assign(aStr);
155
26.5k
    return *this;
156
26.5k
  }
nsTString<char16_t>::operator=(nsTSubstring<char16_t> const&)
Line
Count
Source
153
21.9k
  {
154
21.9k
    this->Assign(aStr);
155
21.9k
    return *this;
156
21.9k
  }
nsTString<char>::operator=(nsTSubstring<char> const&)
Line
Count
Source
153
4.58k
  {
154
4.58k
    this->Assign(aStr);
155
4.58k
    return *this;
156
4.58k
  }
157
  self_type& operator=(substring_type&& aStr)
158
0
  {
159
0
    this->Assign(std::move(aStr));
160
0
    return *this;
161
0
  }
Unexecuted instantiation: nsTString<char>::operator=(nsTSubstring<char>&&)
Unexecuted instantiation: nsTString<char16_t>::operator=(nsTSubstring<char16_t>&&)
162
  self_type& operator=(const substring_tuple_type& aTuple)
163
0
  {
164
0
    this->Assign(aTuple);
165
0
    return *this;
166
0
  }
Unexecuted instantiation: nsTString<char>::operator=(nsTSubstringTuple<char> const&)
Unexecuted instantiation: nsTString<char16_t>::operator=(nsTSubstringTuple<char16_t> const&)
167
168
  /**
169
   * returns the null-terminated string
170
   */
171
172
  template <typename U, typename Dummy> struct raw_type { typedef const U* type; };
173
#if defined(MOZ_USE_CHAR16_WRAPPER)
174
  template <typename Dummy> struct raw_type<char16_t, Dummy> { typedef char16ptr_t type; };
175
#endif
176
177
  MOZ_NO_DANGLING_ON_TEMPORARIES typename raw_type<T, int>::type get() const
178
689k
  {
179
689k
    return this->mData;
180
689k
  }
181
182
183
  /**
184
   * returns character at specified index.
185
   *
186
   * NOTE: unlike nsTSubstring::CharAt, this function allows you to index
187
   *       the null terminator character.
188
   */
189
190
  char_type CharAt(index_type aIndex) const
191
0
  {
192
0
    NS_ASSERTION(aIndex <= this->mLength, "index exceeds allowable range");
193
0
    return this->mData[aIndex];
194
0
  }
195
196
  char_type operator[](index_type aIndex) const
197
0
  {
198
0
    return CharAt(aIndex);
199
0
  }
200
201
202
#if MOZ_STRING_WITH_OBSOLETE_API
203
204
205
  /**
206
   *  Search for the given substring within this string.
207
   *
208
   *  @param   aString is substring to be sought in this
209
   *  @param   aIgnoreCase selects case sensitivity
210
   *  @param   aOffset tells us where in this string to start searching
211
   *  @param   aCount tells us how far from the offset we are to search. Use
212
   *           -1 to search the whole string.
213
   *  @return  offset in string, or kNotFound
214
   */
215
216
  int32_t Find(const nsTString<char>& aString, bool aIgnoreCase = false,
217
               int32_t aOffset = 0, int32_t aCount = -1) const;
218
  int32_t Find(const char* aString, bool aIgnoreCase = false,
219
               int32_t aOffset = 0, int32_t aCount = -1) const;
220
221
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
222
  int32_t Find(const self_type& aString, int32_t aOffset = 0,
223
               int32_t aCount = -1) const;
224
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
225
  int32_t Find(const char_type* aString, int32_t aOffset = 0,
226
               int32_t aCount = -1) const;
227
#ifdef MOZ_USE_CHAR16_WRAPPER
228
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
229
  int32_t Find(char16ptr_t aString, int32_t aOffset = 0,
230
               int32_t aCount = -1) const
231
  {
232
    return Find(static_cast<const char16_t*>(aString), aOffset, aCount);
233
  }
234
#endif
235
236
237
  /**
238
   * This methods scans the string backwards, looking for the given string
239
   *
240
   * @param   aString is substring to be sought in this
241
   * @param   aIgnoreCase tells us whether or not to do caseless compare
242
   * @param   aOffset tells us where in this string to start searching.
243
   *          Use -1 to search from the end of the string.
244
   * @param   aCount tells us how many iterations to make starting at the
245
   *          given offset.
246
   * @return  offset in string, or kNotFound
247
   */
248
249
  // Case aIgnoreCase option only with char versions
250
  int32_t RFind(const nsTString<char>& aString, bool aIgnoreCase = false,
251
                int32_t aOffset = -1, int32_t aCount = -1) const;
252
  int32_t RFind(const char* aCString, bool aIgnoreCase = false,
253
                int32_t aOffset = -1, int32_t aCount = -1) const;
254
255
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
256
  int32_t RFind(const self_type& aString, int32_t aOffset = -1,
257
                int32_t aCount = -1) const;
258
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
259
  int32_t RFind(const char_type* aString, int32_t aOffset = -1,
260
                int32_t aCount = -1) const;
261
262
263
  /**
264
   *  Search for given char within this string
265
   *
266
   *  @param   aChar is the character to search for
267
   *  @param   aOffset tells us where in this string to start searching
268
   *  @param   aCount tells us how far from the offset we are to search.
269
   *           Use -1 to search the whole string.
270
   *  @return  offset in string, or kNotFound
271
   */
272
273
  // int32_t FindChar( char16_t aChar, int32_t aOffset=0, int32_t aCount=-1 ) const;
274
  int32_t RFindChar(char16_t aChar, int32_t aOffset = -1,
275
                    int32_t aCount = -1) const;
276
277
278
  /**
279
   * This method searches this string for the first character found in
280
   * the given string.
281
   *
282
   * @param aString contains set of chars to be found
283
   * @param aOffset tells us where in this string to start searching
284
   *        (counting from left)
285
   * @return offset in string, or kNotFound
286
   */
287
288
  int32_t FindCharInSet(const char_type* aString, int32_t aOffset = 0) const;
289
  int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const
290
31.7k
  {
291
31.7k
    return FindCharInSet(aString.get(), aOffset);
292
31.7k
  }
nsTString<char>::FindCharInSet(nsTString<char> const&, int) const
Line
Count
Source
290
4.94k
  {
291
4.94k
    return FindCharInSet(aString.get(), aOffset);
292
4.94k
  }
nsTString<char16_t>::FindCharInSet(nsTString<char16_t> const&, int) const
Line
Count
Source
290
26.8k
  {
291
26.8k
    return FindCharInSet(aString.get(), aOffset);
292
26.8k
  }
293
294
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
295
  int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const;
296
297
298
  /**
299
   * This method searches this string for the last character found in
300
   * the given string.
301
   *
302
   * @param aString contains set of chars to be found
303
   * @param aOffset tells us where in this string to start searching
304
   *        (counting from left)
305
   * @return offset in string, or kNotFound
306
   */
307
308
  int32_t RFindCharInSet(const char_type* aString, int32_t aOffset = -1) const;
309
  int32_t RFindCharInSet(const self_type& aString, int32_t aOffset = -1) const
310
0
  {
311
0
    return RFindCharInSet(aString.get(), aOffset);
312
0
  }
Unexecuted instantiation: nsTString<char>::RFindCharInSet(nsTString<char> const&, int) const
Unexecuted instantiation: nsTString<char16_t>::RFindCharInSet(nsTString<char16_t> const&, int) const
313
314
315
  /**
316
   * Compares a given string to this string.
317
   *
318
   * @param   aString is the string to be compared
319
   * @param   aIgnoreCase tells us how to treat case
320
   * @param   aCount tells us how many chars to compare
321
   * @return  -1,0,1
322
   */
323
  template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
324
  int32_t Compare(const char_type* aString, bool aIgnoreCase = false,
325
                  int32_t aCount = -1) const;
326
327
328
  /**
329
   * Equality check between given string and this string.
330
   *
331
   * @param   aString is the string to check
332
   * @param   aIgnoreCase tells us how to treat case
333
   * @param   aCount tells us how many chars to compare
334
   * @return  boolean
335
   */
336
  template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
337
  bool EqualsIgnoreCase(const char_type* aString, int32_t aCount = -1) const
338
  {
339
    return Compare(aString, true, aCount) == 0;
340
  }
341
342
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
343
  bool EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount = -1) const;
344
345
  /**
346
   * Perform string to double-precision float conversion.
347
   *
348
   * @param   aErrorCode will contain error if one occurs
349
   * @return  double-precision float rep of string value
350
   */
351
  double ToDouble(nsresult* aErrorCode) const;
352
353
  /**
354
   * Perform string to single-precision float conversion.
355
   *
356
   * @param   aErrorCode will contain error if one occurs
357
   * @return  single-precision float rep of string value
358
   */
359
  float ToFloat(nsresult* aErrorCode) const;
360
361
  /**
362
   * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
363
   * any _other_ way than they are now.  Consider these alternatives
364
   *
365
   * aWritable = aReadable.Left(17);   // ...a member function that returns a |Substring|
366
   * aWritable = Left(aReadable, 17);  // ...a global function that returns a |Substring|
367
   * Left(aReadable, 17, aWritable);   // ...a global function that does the assignment
368
   *
369
   * as opposed to the current signature
370
   *
371
   * aReadable.Left(aWritable, 17);    // ...a member function that does the assignment
372
   *
373
   * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
374
   *
375
   * aWritable = Substring(aReadable, 0, 17);
376
   */
377
378
  size_type Mid(self_type& aResult, index_type aStartPos, size_type aCount) const;
379
380
  size_type Left(self_type& aResult, size_type aCount) const
381
0
  {
382
0
    return Mid(aResult, 0, aCount);
383
0
  }
384
385
  size_type Right(self_type& aResult, size_type aCount) const
386
0
  {
387
0
    aCount = XPCOM_MIN(this->mLength, aCount);
388
0
    return Mid(aResult, this->mLength - aCount, aCount);
389
0
  }
390
391
392
  /**
393
   * Set a char inside this string at given index
394
   *
395
   * @param aChar is the char you want to write into this string
396
   * @param anIndex is the ofs where you want to write the given char
397
   * @return TRUE if successful
398
   */
399
400
  bool SetCharAt(char16_t aChar, uint32_t aIndex);
401
402
403
  /**
404
   *  These methods are used to remove all occurrences of the
405
   *  characters found in aSet from this string.
406
   *
407
   *  @param  aSet -- characters to be cut from this
408
   */
409
  void StripChars(const char_type* aSet);
410
411
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
412
  bool StripChars(const incompatible_char_type* aSet, const fallible_t&);
413
414
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
415
  void StripChars(const incompatible_char_type* aSet);
416
417
  /**
418
   *  This method strips whitespace throughout the string.
419
   */
420
  void StripWhitespace();
421
  bool StripWhitespace(const fallible_t&);
422
423
424
  /**
425
   *  swaps occurence of 1 string for another
426
   */
427
428
  void ReplaceChar(char_type aOldChar, char_type aNewChar);
429
  void ReplaceChar(const char_type* aSet, char_type aNewChar);
430
431
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
432
  void ReplaceChar(const char* aSet, char16_t aNewChar);
433
434
  /**
435
   * Replace all occurrences of aTarget with aNewValue.
436
   * The complexity of this function is O(n+m), n being the length of the string
437
   * and m being the length of aNewValue.
438
   */
439
  void ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue);
440
  void ReplaceSubstring(const char_type* aTarget, const char_type* aNewValue);
441
  MOZ_MUST_USE bool ReplaceSubstring(const self_type& aTarget,
442
                                     const self_type& aNewValue,
443
                                     const fallible_t&);
444
  MOZ_MUST_USE bool ReplaceSubstring(const char_type* aTarget,
445
                                     const char_type* aNewValue,
446
                                     const fallible_t&);
447
448
449
  /**
450
   *  This method trims characters found in aTrimSet from
451
   *  either end of the underlying string.
452
   *
453
   *  @param   aSet -- contains chars to be trimmed from both ends
454
   *  @param   aEliminateLeading
455
   *  @param   aEliminateTrailing
456
   *  @param   aIgnoreQuotes -- if true, causes surrounding quotes to be ignored
457
   *  @return  this
458
   */
459
  void Trim(const char* aSet, bool aEliminateLeading = true,
460
            bool aEliminateTrailing = true, bool aIgnoreQuotes = false);
461
462
  /**
463
   *  This method strips whitespace from string.
464
   *  You can control whether whitespace is yanked from start and end of
465
   *  string as well.
466
   *
467
   *  @param   aEliminateLeading controls stripping of leading ws
468
   *  @param   aEliminateTrailing controls stripping of trailing ws
469
   */
470
  void CompressWhitespace(bool aEliminateLeading = true,
471
                          bool aEliminateTrailing = true);
472
473
#endif // !MOZ_STRING_WITH_OBSOLETE_API
474
475
  /**
476
   * Allow this string to be bound to a character buffer
477
   * until the string is rebound or mutated; the caller
478
   * must ensure that the buffer outlives the string.
479
   */
480
  void Rebind(const char_type* aData, size_type aLength);
481
482
  /**
483
   * verify restrictions for dependent strings
484
   */
485
  void AssertValidDependentString()
486
421k
  {
487
421k
    NS_ASSERTION(this->mData, "nsTDependentString must wrap a non-NULL buffer");
488
421k
    NS_ASSERTION(this->mLength != size_type(-1), "nsTDependentString has bogus length");
489
421k
    NS_ASSERTION(this->mData[substring_type::mLength] == 0,
490
421k
                 "nsTDependentString must wrap only null-terminated strings. "
491
421k
                 "You are probably looking for nsTDependentSubstring.");
492
421k
  }
493
494
495
protected:
496
497
  // allow subclasses to initialize fields directly
498
  nsTString(char_type* aData, size_type aLength, DataFlags aDataFlags,
499
            ClassFlags aClassFlags)
500
    : substring_type(aData, aLength, aDataFlags,
501
                     aClassFlags | ClassFlags::NULL_TERMINATED)
502
  {
503
  }
504
505
  friend const nsTString<char>& VoidCString();
506
  friend const nsTString<char16_t>& VoidString();
507
508
  // Used by Null[C]String.
509
  explicit nsTString(DataFlags aDataFlags)
510
    : substring_type(char_traits::sEmptyBuffer, 0,
511
                     aDataFlags | DataFlags::TERMINATED,
512
                     ClassFlags::NULL_TERMINATED)
513
3
  {}
nsTString<char>::nsTString(mozilla::detail::StringDataFlags)
Line
Count
Source
513
3
  {}
Unexecuted instantiation: nsTString<char16_t>::nsTString(mozilla::detail::StringDataFlags)
514
515
  struct Segment {
516
    uint32_t mBegin, mLength;
517
    Segment(uint32_t aBegin, uint32_t aLength)
518
      : mBegin(aBegin)
519
      , mLength(aLength)
520
349
    {}
nsTString<char>::Segment::Segment(unsigned int, unsigned int)
Line
Count
Source
520
349
    {}
Unexecuted instantiation: nsTString<char16_t>::Segment::Segment(unsigned int, unsigned int)
521
  };
522
};
523
524
// TODO(erahm): Do something with ToDouble so that we can extern the
525
// nsTString templates.
526
//extern template class nsTString<char>;
527
//extern template class nsTString<char16_t>;
528
529
/**
530
 * nsTAutoStringN
531
 *
532
 * Subclass of nsTString that adds support for stack-based string
533
 * allocation.  It is normally not a good idea to use this class on the
534
 * heap, because it will allocate space which may be wasted if the string
535
 * it contains is significantly smaller or any larger than 64 characters.
536
 *
537
 * NAMES:
538
 *   nsAutoStringN / nsTAutoString for wide characters
539
 *   nsAutoCStringN / nsTAutoCString for narrow characters
540
 */
541
template<typename T, size_t N>
542
class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTString<T>
543
{
544
public:
545
546
  typedef nsTAutoStringN<T, N> self_type;
547
548
  typedef nsTString<T> base_string_type;
549
  typedef typename base_string_type::string_type string_type;
550
  typedef typename base_string_type::char_type char_type;
551
  typedef typename base_string_type::char_traits char_traits;
552
  typedef typename base_string_type::substring_type substring_type;
553
  typedef typename base_string_type::size_type size_type;
554
  typedef typename base_string_type::substring_tuple_type substring_tuple_type;
555
556
  // These are only for internal use within the string classes:
557
  typedef typename base_string_type::DataFlags DataFlags;
558
  typedef typename base_string_type::ClassFlags ClassFlags;
559
560
public:
561
562
  /**
563
   * constructors
564
   */
565
566
  nsTAutoStringN()
567
    : string_type(mStorage, 0, DataFlags::TERMINATED | DataFlags::INLINE,
568
                  ClassFlags::INLINE)
569
    , mInlineCapacity(N - 1)
570
  {
571
    // null-terminate
572
    mStorage[0] = char_type(0);
573
  }
574
575
  explicit
576
  nsTAutoStringN(char_type aChar)
577
    : self_type()
578
0
  {
579
0
    this->Assign(aChar);
580
0
  }
Unexecuted instantiation: nsTAutoStringN<char, 64ul>::nsTAutoStringN(char)
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(char16_t)
581
582
  explicit
583
  nsTAutoStringN(const char_type* aData, size_type aLength = size_type(-1))
584
    : self_type()
585
0
  {
586
0
    this->Assign(aData, aLength);
587
0
  }
588
589
#if defined(MOZ_USE_CHAR16_WRAPPER)
590
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
591
  explicit
592
  nsTAutoStringN(char16ptr_t aData, size_type aLength = size_type(-1))
593
    : self_type(static_cast<const char16_t*>(aData), aLength)
594
  {
595
  }
596
#endif
597
598
  nsTAutoStringN(const self_type& aStr)
599
    : self_type()
600
0
  {
601
0
    this->Assign(aStr);
602
0
  }
603
604
  nsTAutoStringN(self_type&& aStr)
605
    : self_type()
606
9.49k
  {
607
9.49k
    this->Assign(std::move(aStr));
608
9.49k
  }
nsTAutoStringN<char, 64ul>::nsTAutoStringN(nsTAutoStringN<char, 64ul>&&)
Line
Count
Source
606
9.49k
  {
607
9.49k
    this->Assign(std::move(aStr));
608
9.49k
  }
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(nsTAutoStringN<char16_t, 64ul>&&)
609
610
  explicit
611
  nsTAutoStringN(const substring_type& aStr)
612
    : self_type()
613
2.20k
  {
614
2.20k
    this->Assign(aStr);
615
2.20k
  }
616
617
  explicit
618
  nsTAutoStringN(substring_type&& aStr)
619
    : self_type()
620
3.86M
  {
621
3.86M
    this->Assign(std::move(aStr));
622
3.86M
  }
nsTAutoStringN<char, 64ul>::nsTAutoStringN(nsTSubstring<char>&&)
Line
Count
Source
620
3.86M
  {
621
3.86M
    this->Assign(std::move(aStr));
622
3.86M
  }
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(nsTSubstring<char16_t>&&)
623
624
  MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple)
625
    : self_type()
626
2.22k
  {
627
2.22k
    this->Assign(aTuple);
628
2.22k
  }
nsTAutoStringN<char, 64ul>::nsTAutoStringN(nsTSubstringTuple<char> const&)
Line
Count
Source
626
2.22k
  {
627
2.22k
    this->Assign(aTuple);
628
2.22k
  }
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(nsTSubstringTuple<char16_t> const&)
629
630
  // |operator=| does not inherit, so we must define our own
631
  self_type& operator=(char_type aChar)
632
0
  {
633
0
    this->Assign(aChar);
634
0
    return *this;
635
0
  }
Unexecuted instantiation: nsTAutoStringN<char, 64ul>::operator=(char)
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(char16_t)
636
  self_type& operator=(const char_type* aData)
637
2
  {
638
2
    this->Assign(aData);
639
2
    return *this;
640
2
  }
nsTAutoStringN<char, 64ul>::operator=(char const*)
Line
Count
Source
637
2
  {
638
2
    this->Assign(aData);
639
2
    return *this;
640
2
  }
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(char16_t const*)
641
#if defined(MOZ_USE_CHAR16_WRAPPER)
642
  template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
643
  self_type& operator=(char16ptr_t aStr)
644
  {
645
    this->Assign(aStr);
646
    return *this;
647
  }
648
#endif
649
  self_type& operator=(const self_type& aStr)
650
0
  {
651
0
    this->Assign(aStr);
652
0
    return *this;
653
0
  }
654
  self_type& operator=(self_type&& aStr)
655
5
  {
656
5
    this->Assign(std::move(aStr));
657
5
    return *this;
658
5
  }
nsTAutoStringN<char, 64ul>::operator=(nsTAutoStringN<char, 64ul>&&)
Line
Count
Source
655
5
  {
656
5
    this->Assign(std::move(aStr));
657
5
    return *this;
658
5
  }
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(nsTAutoStringN<char16_t, 64ul>&&)
659
  self_type& operator=(const substring_type& aStr)
660
12
  {
661
12
    this->Assign(aStr);
662
12
    return *this;
663
12
  }
664
  self_type& operator=(substring_type&& aStr)
665
0
  {
666
0
    this->Assign(std::move(aStr));
667
0
    return *this;
668
0
  }
Unexecuted instantiation: nsTAutoStringN<char, 64ul>::operator=(nsTSubstring<char>&&)
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(nsTSubstring<char16_t>&&)
669
  self_type& operator=(const substring_tuple_type& aTuple)
670
0
  {
671
0
    this->Assign(aTuple);
672
0
    return *this;
673
0
  }
Unexecuted instantiation: nsTAutoStringN<char, 64ul>::operator=(nsTSubstringTuple<char> const&)
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(nsTSubstringTuple<char16_t> const&)
674
675
  static const size_t kStorageSize = N;
676
677
protected:
678
  friend class nsTSubstring<T>;
679
680
  size_type mInlineCapacity;
681
682
private:
683
  char_type mStorage[N];
684
};
685
686
// Externs for the most common nsTAutoStringN variations.
687
extern template class nsTAutoStringN<char, 64>;
688
extern template class nsTAutoStringN<char16_t, 64>;
689
690
//
691
// nsAutoString stores pointers into itself which are invalidated when an
692
// nsTArray is resized, so nsTArray must not be instantiated with nsAutoString
693
// elements!
694
//
695
template<class E> class nsTArrayElementTraits;
696
template<typename T>
697
class nsTArrayElementTraits<nsTAutoString<T>>
698
{
699
public:
700
  template<class A> struct Dont_Instantiate_nsTArray_of;
701
  template<class A> struct Instead_Use_nsTArray_of;
702
703
  static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
704
  Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE)
705
  {
706
    return 0;
707
  }
708
  template<class A>
709
  static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
710
  Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE, const A& aArg)
711
  {
712
    return 0;
713
  }
714
  static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
715
  Destruct(Instead_Use_nsTArray_of<nsTString<T>>* aE)
716
  {
717
    return 0;
718
  }
719
};
720
721
/**
722
 * getter_Copies support for adopting raw string out params that are
723
 * heap-allocated, e.g.:
724
 *
725
 *    char* gStr;
726
 *    void GetBlah(char** aStr)
727
 *    {
728
 *      *aStr = strdup(gStr);
729
 *    }
730
 *
731
 *    // This works, but is clumsy.
732
 *    void Inelegant()
733
 *    {
734
 *      char* buf;
735
 *      GetBlah(&buf);
736
 *      nsCString str;
737
 *      str.Adopt(buf);
738
 *      // ...
739
 *    }
740
 *
741
 *    // This is nicer.
742
 *    void Elegant()
743
 *    {
744
 *      nsCString str;
745
 *      GetBlah(getter_Copies(str));
746
 *      // ...
747
 *    }
748
 */
749
template <typename T>
750
class MOZ_STACK_CLASS nsTGetterCopies
751
{
752
public:
753
  typedef T char_type;
754
755
  explicit nsTGetterCopies(nsTSubstring<T>& aStr)
756
    : mString(aStr)
757
    , mData(nullptr)
758
  {
759
  }
760
761
  ~nsTGetterCopies()
762
  {
763
    mString.Adopt(mData); // OK if mData is null
764
  }
765
766
  operator char_type**()
767
  {
768
    return &mData;
769
  }
770
771
private:
772
  nsTSubstring<T>& mString;
773
  char_type* mData;
774
};
775
776
// See the comment above nsTGetterCopies_CharT for how to use this.
777
template <typename T>
778
inline nsTGetterCopies<T>
779
getter_Copies(nsTSubstring<T>& aString)
780
{
781
  return nsTGetterCopies<T>(aString);
782
}
783
784
#endif