1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /**
8  * This header provides wrapper classes around the frozen string API
9  * which are roughly equivalent to the internal string classes.
10  */
11 
12 #ifdef MOZILLA_INTERNAL_API
13 #error nsStringAPI.h is only usable from non-MOZILLA_INTERNAL_API code!
14 #endif
15 
16 #ifndef nsStringAPI_h__
17 #define nsStringAPI_h__
18 
19 #include "mozilla/Attributes.h"
20 #include "mozilla/Char16.h"
21 
22 #include "nsXPCOMStrings.h"
23 #include "nsISupportsImpl.h"
24 #include "mozilla/Logging.h"
25 #include "nsTArray.h"
26 
27 /**
28  * Comparison function for use with nsACString::Equals
29  */
30 NS_HIDDEN_(int32_t) CaseInsensitiveCompare(const char* aStrA, const char* aStrB,
31                                            uint32_t aLength);
32 
33 class nsAString
34 {
35 public:
36   typedef char16_t  char_type;
37   typedef nsAString self_type;
38   typedef uint32_t  size_type;
39   typedef uint32_t  index_type;
40 
41   /**
42    * Returns the length, beginning, and end of a string in one operation.
43    */
44   NS_HIDDEN_(uint32_t) BeginReading(const char_type** aBegin,
45                                     const char_type** aEnd = nullptr) const;
46 
47   NS_HIDDEN_(const char_type*) BeginReading() const;
48   NS_HIDDEN_(const char_type*) EndReading() const;
49 
CharAt(uint32_t aPos)50   NS_HIDDEN_(char_type) CharAt(uint32_t aPos) const
51   {
52     NS_ASSERTION(aPos < Length(), "Out of bounds");
53     return BeginReading()[aPos];
54   }
NS_HIDDEN_(char_type)55   NS_HIDDEN_(char_type) operator [](uint32_t aPos) const
56   {
57     return CharAt(aPos);
58   }
First()59   NS_HIDDEN_(char_type) First() const
60   {
61     return CharAt(0);
62   }
Last()63   NS_HIDDEN_(char_type) Last() const
64   {
65     const char_type* data;
66     uint32_t dataLen = NS_StringGetData(*this, &data);
67     return data[dataLen - 1];
68   }
69 
70   /**
71    * Get the length, begin writing, and optionally set the length of a
72    * string all in one operation.
73    *
74    * @param   newSize Size the string to this length. Pass UINT32_MAX
75    *                  to leave the length unchanged.
76    * @return  The new length of the string, or 0 if resizing failed.
77    */
78   NS_HIDDEN_(uint32_t) BeginWriting(char_type** aBegin,
79                                     char_type** aEnd = nullptr,
80                                     uint32_t aNewSize = UINT32_MAX);
81 
82   NS_HIDDEN_(char_type*) BeginWriting(uint32_t = UINT32_MAX);
83   NS_HIDDEN_(char_type*) EndWriting();
84 
85   NS_HIDDEN_(bool) SetLength(uint32_t aLen);
86 
Length()87   NS_HIDDEN_(size_type) Length() const
88   {
89     const char_type* data;
90     return NS_StringGetData(*this, &data);
91   }
92 
IsEmpty()93   NS_HIDDEN_(bool) IsEmpty() const { return Length() == 0; }
94 
SetIsVoid(bool aVal)95   NS_HIDDEN_(void) SetIsVoid(bool aVal) { NS_StringSetIsVoid(*this, aVal); }
IsVoid()96   NS_HIDDEN_(bool) IsVoid() const { return NS_StringGetIsVoid(*this); }
97 
Assign(const self_type & aString)98   NS_HIDDEN_(void) Assign(const self_type& aString)
99   {
100     NS_StringCopy(*this, aString);
101   }
102   NS_HIDDEN_(void) Assign(const char_type* aData, size_type aLength = UINT32_MAX)
103   {
104     NS_StringSetData(*this, aData, aLength);
105   }
Assign(char_type aChar)106   NS_HIDDEN_(void) Assign(char_type aChar)
107   {
108     NS_StringSetData(*this, &aChar, 1);
109   }
110 #ifdef MOZ_USE_CHAR16_WRAPPER
111   NS_HIDDEN_(void) Assign(char16ptr_t aData, size_type aLength = UINT32_MAX)
112   {
113     NS_StringSetData(*this, aData, aLength);
114   }
115 #endif
116 
117   NS_HIDDEN_(void) AssignLiteral(const char* aStr);
AssignASCII(const char * aStr)118   NS_HIDDEN_(void) AssignASCII(const char* aStr)
119   {
120     AssignLiteral(aStr);
121   }
122 
NS_HIDDEN_(self_type &)123   NS_HIDDEN_(self_type&) operator=(const self_type& aString)
124   {
125     Assign(aString);
126     return *this;
127   }
NS_HIDDEN_(self_type &)128   NS_HIDDEN_(self_type&) operator=(const char_type* aPtr)
129   {
130     Assign(aPtr);
131     return *this;
132   }
NS_HIDDEN_(self_type &)133   NS_HIDDEN_(self_type&) operator=(char_type aChar)
134   {
135     Assign(aChar);
136     return *this;
137   }
138 #ifdef MOZ_USE_CHAR16_WRAPPER
NS_HIDDEN_(self_type &)139   NS_HIDDEN_(self_type&) operator=(char16ptr_t aPtr)
140   {
141     Assign(aPtr);
142     return *this;
143   }
144 #endif
145 
146   NS_HIDDEN_(void) Replace(index_type aCutStart, size_type aCutLength,
147                            const char_type* aData,
148                            size_type aLength = size_type(-1))
149   {
150     NS_StringSetDataRange(*this, aCutStart, aCutLength, aData, aLength);
151   }
Replace(index_type aCutStart,size_type aCutLength,char_type aChar)152   NS_HIDDEN_(void) Replace(index_type aCutStart, size_type aCutLength,
153                            char_type aChar)
154   {
155     Replace(aCutStart, aCutLength, &aChar, 1);
156   }
Replace(index_type aCutStart,size_type aCutLength,const self_type & aReadable)157   NS_HIDDEN_(void) Replace(index_type aCutStart, size_type aCutLength,
158                            const self_type& aReadable)
159   {
160     const char_type* data;
161     uint32_t dataLen = NS_StringGetData(aReadable, &data);
162     NS_StringSetDataRange(*this, aCutStart, aCutLength, data, dataLen);
163   }
SetCharAt(char_type aChar,index_type aPos)164   NS_HIDDEN_(void) SetCharAt(char_type aChar, index_type aPos)
165   {
166     Replace(aPos, 1, &aChar, 1);
167   }
168 
Append(char_type aChar)169   NS_HIDDEN_(void) Append(char_type aChar)
170   {
171     Replace(size_type(-1), 0, aChar);
172   }
173   NS_HIDDEN_(void) Append(const char_type* aData,
174                           size_type aLength = size_type(-1))
175   {
176     Replace(size_type(-1), 0, aData, aLength);
177   }
178 #ifdef MOZ_USE_CHAR16_WRAPPER
179   NS_HIDDEN_(void) Append(char16ptr_t aData, size_type aLength = size_type(-1))
180   {
181     Append(static_cast<const char16_t*>(aData), aLength);
182   }
183 #endif
Append(const self_type & aReadable)184   NS_HIDDEN_(void) Append(const self_type& aReadable)
185   {
186     Replace(size_type(-1), 0, aReadable);
187   }
188   NS_HIDDEN_(void) AppendLiteral(const char* aASCIIStr);
AppendASCII(const char * aASCIIStr)189   NS_HIDDEN_(void) AppendASCII(const char* aASCIIStr)
190   {
191     AppendLiteral(aASCIIStr);
192   }
193 
194   NS_HIDDEN_(self_type&) operator+=(char_type aChar)
195   {
196     Append(aChar);
197     return *this;
198   }
199   NS_HIDDEN_(self_type&) operator+=(const char_type* aData)
200   {
201     Append(aData);
202     return *this;
203   }
204   NS_HIDDEN_(self_type&) operator+=(const self_type& aReadable)
205   {
206     Append(aReadable);
207     return *this;
208   }
209 
Insert(char_type aChar,index_type aPos)210   NS_HIDDEN_(void) Insert(char_type aChar, index_type aPos)
211   {
212     Replace(aPos, 0, aChar);
213   }
214   NS_HIDDEN_(void) Insert(const char_type* aData, index_type aPos,
215                           size_type aLength = size_type(-1))
216   {
217     Replace(aPos, 0, aData, aLength);
218   }
Insert(const self_type & aReadable,index_type aPos)219   NS_HIDDEN_(void) Insert(const self_type& aReadable, index_type aPos)
220   {
221     Replace(aPos, 0, aReadable);
222   }
223 
Cut(index_type aCutStart,size_type aCutLength)224   NS_HIDDEN_(void) Cut(index_type aCutStart, size_type aCutLength)
225   {
226     Replace(aCutStart, aCutLength, nullptr, 0);
227   }
228 
229   NS_HIDDEN_(void) Truncate(size_type aNewLength = 0)
230   {
231     NS_ASSERTION(aNewLength <= Length(), "Truncate cannot make string longer");
232     SetLength(aNewLength);
233   }
234 
235   /**
236    * Remove all occurences of characters in aSet from the string.
237    */
238   NS_HIDDEN_(void) StripChars(const char* aSet);
239 
240   /**
241    * Strip whitespace characters from the string.
242    */
StripWhitespace()243   NS_HIDDEN_(void) StripWhitespace() { StripChars("\b\t\r\n "); }
244 
245   NS_HIDDEN_(void) Trim(const char* aSet, bool aLeading = true,
246                         bool aTrailing = true);
247 
248   /**
249    * Compare strings of characters. Return 0 if the characters are equal,
250    */
251   typedef int32_t (*ComparatorFunc)(const char_type* aStrA,
252                                     const char_type* aStrB,
253                                     uint32_t aLength);
254 
255   static NS_HIDDEN_(int32_t) DefaultComparator(const char_type* aStrA,
256                                                const char_type* aStrB,
257                                                uint32_t aLength);
258 
259   NS_HIDDEN_(int32_t) Compare(const char_type* aOther,
260                               ComparatorFunc aComparator = DefaultComparator) const;
261 
262   NS_HIDDEN_(int32_t) Compare(const self_type& aOther,
263                               ComparatorFunc aComparator = DefaultComparator) const;
264 
265   NS_HIDDEN_(bool) Equals(const char_type* aOther,
266                           ComparatorFunc aComparator = DefaultComparator) const;
267 
268   NS_HIDDEN_(bool) Equals(const self_type& aOther,
269                           ComparatorFunc aComparator = DefaultComparator) const;
270 
271   NS_HIDDEN_(bool) operator<(const self_type& aOther) const
272   {
273     return Compare(aOther) < 0;
274   }
275   NS_HIDDEN_(bool) operator<(const char_type* aOther) const
276   {
277     return Compare(aOther) < 0;
278   }
279 
280   NS_HIDDEN_(bool) operator<=(const self_type& aOther) const
281   {
282     return Compare(aOther) <= 0;
283   }
284   NS_HIDDEN_(bool) operator<=(const char_type* aOther) const
285   {
286     return Compare(aOther) <= 0;
287   }
288 
289   NS_HIDDEN_(bool) operator==(const self_type& aOther) const
290   {
291     return Equals(aOther);
292   }
293   NS_HIDDEN_(bool) operator==(const char_type* aOther) const
294   {
295     return Equals(aOther);
296   }
297 #ifdef MOZ_USE_CHAR16_WRAPPER
298   NS_HIDDEN_(bool) operator==(char16ptr_t aOther) const
299   {
300     return Equals(aOther);
301   }
302 #endif
303 
NS_HIDDEN_(bool)304   NS_HIDDEN_(bool) operator>=(const self_type& aOther) const
305   {
306     return Compare(aOther) >= 0;
307   }
NS_HIDDEN_(bool)308   NS_HIDDEN_(bool) operator>=(const char_type* aOther) const
309   {
310     return Compare(aOther) >= 0;
311   }
312 
NS_HIDDEN_(bool)313   NS_HIDDEN_(bool) operator>(const self_type& aOther) const
314   {
315     return Compare(aOther) > 0;
316   }
NS_HIDDEN_(bool)317   NS_HIDDEN_(bool) operator>(const char_type* aOther) const
318   {
319     return Compare(aOther) > 0;
320   }
321 
322   NS_HIDDEN_(bool) operator!=(const self_type& aOther) const
323   {
324     return !Equals(aOther);
325   }
326   NS_HIDDEN_(bool) operator!=(const char_type* aOther) const
327   {
328     return !Equals(aOther);
329   }
330 
331   NS_HIDDEN_(bool) EqualsLiteral(const char* aASCIIString) const;
EqualsASCII(const char * aASCIIString)332   NS_HIDDEN_(bool) EqualsASCII(const char* aASCIIString) const
333   {
334     return EqualsLiteral(aASCIIString);
335   }
336 
337   /**
338    * Case-insensitive match this string to a lowercase ASCII string.
339    */
340   NS_HIDDEN_(bool) LowerCaseEqualsLiteral(const char* aASCIIString) const;
341 
342   /**
343    * Find the first occurrence of aStr in this string.
344    *
345    * @return the offset of aStr, or -1 if not found
346    */
347   NS_HIDDEN_(int32_t) Find(const self_type& aStr,
348                            ComparatorFunc aComparator = DefaultComparator) const
349   {
350     return Find(aStr, 0, aComparator);
351   }
352 
353   /**
354    * Find the first occurrence of aStr in this string, beginning at aOffset.
355    *
356    * @return the offset of aStr, or -1 if not found
357    */
358   NS_HIDDEN_(int32_t) Find(const self_type& aStr, uint32_t aOffset,
359                            ComparatorFunc aComparator = DefaultComparator) const;
360 
361   /**
362    * Find an ASCII string within this string.
363    *
364    * @return the offset of aStr, or -1 if not found.
365    */
366   NS_HIDDEN_(int32_t) Find(const char* aStr, bool aIgnoreCase = false) const
367   {
368     return Find(aStr, 0, aIgnoreCase);
369   }
370 
371   NS_HIDDEN_(int32_t) Find(const char* aStr, uint32_t aOffset,
372                            bool aIgnoreCase = false) const;
373 
374   /**
375    * Find the last occurrence of aStr in this string.
376    *
377    * @return The offset of aStr from the beginning of the string,
378    *         or -1 if not found.
379    */
380   NS_HIDDEN_(int32_t) RFind(const self_type& aStr,
381                             ComparatorFunc aComparator = DefaultComparator) const
382   {
383     return RFind(aStr, -1, aComparator);
384   }
385 
386   /**
387    * Find the last occurrence of aStr in this string, beginning at aOffset.
388    *
389    * @param aOffset the offset from the beginning of the string to begin
390    *        searching. If aOffset < 0, search from end of this string.
391    * @return The offset of aStr from the beginning of the string,
392    *         or -1 if not found.
393    */
394   NS_HIDDEN_(int32_t) RFind(const self_type& aStr, int32_t aOffset,
395                             ComparatorFunc aComparator = DefaultComparator) const;
396 
397   /**
398    * Find the last occurrence of an ASCII string within this string.
399    *
400    * @return The offset of aStr from the beginning of the string,
401    *         or -1 if not found.
402    */
403   NS_HIDDEN_(int32_t) RFind(const char* aStr, bool aIgnoreCase = false) const
404   {
405     return RFind(aStr, -1, aIgnoreCase);
406   }
407 
408   /**
409    * Find the last occurrence of an ASCII string beginning at aOffset.
410    *
411    * @param aOffset the offset from the beginning of the string to begin
412    *        searching. If aOffset < 0, search from end of this string.
413    * @return The offset of aStr from the beginning of the string,
414    *         or -1 if not found.
415    */
416   NS_HIDDEN_(int32_t) RFind(const char* aStr, int32_t aOffset,
417                             bool aIgnoreCase) const;
418 
419   /**
420    * Search for the offset of the first occurrence of a character in a
421    * string.
422    *
423    * @param aOffset the offset from the beginning of the string to begin
424    *        searching
425    * @return The offset of the character from the beginning of the string,
426    *         or -1 if not found.
427    */
428   NS_HIDDEN_(int32_t) FindChar(char_type aChar, uint32_t aOffset = 0) const;
429 
430   /**
431    * Search for the offset of the last occurrence of a character in a
432    * string.
433    *
434    * @return The offset of the character from the beginning of the string,
435    *         or -1 if not found.
436    */
437   NS_HIDDEN_(int32_t) RFindChar(char_type aChar) const;
438 
439   /**
440    * Append a string representation of a number.
441    */
442   NS_HIDDEN_(void) AppendInt(int aInt, int32_t aRadix = 10);
443 
444 #ifndef XPCOM_GLUE_AVOID_NSPR
445   /**
446    * Convert this string to an integer.
447    *
448    * @param aErrorCode pointer to contain result code.
449    * @param aRadix must be 10 or 16
450    */
451   NS_HIDDEN_(int32_t) ToInteger(nsresult* aErrorCode,
452                                 uint32_t aRadix = 10) const;
453   /**
454    * Convert this string to a 64-bit integer.
455    *
456    * @param aErrorCode pointer to contain result code.
457    * @param aRadix must be 10 or 16
458    */
459   NS_HIDDEN_(int64_t) ToInteger64(nsresult* aErrorCode,
460                                   uint32_t aRadix = 10) const;
461 #endif // XPCOM_GLUE_AVOID_NSPR
462 
463 protected:
464   // Prevent people from allocating a nsAString directly.
~nsAString()465   ~nsAString() {}
466 };
467 
468 class nsACString
469 {
470 public:
471   typedef char       char_type;
472   typedef nsACString self_type;
473   typedef uint32_t   size_type;
474   typedef uint32_t   index_type;
475 
476   /**
477    * Returns the length, beginning, and end of a string in one operation.
478    */
479   NS_HIDDEN_(uint32_t) BeginReading(const char_type** aBegin,
480                                     const char_type** aEnd = nullptr) const;
481 
482   NS_HIDDEN_(const char_type*) BeginReading() const;
483   NS_HIDDEN_(const char_type*) EndReading() const;
484 
CharAt(uint32_t aPos)485   NS_HIDDEN_(char_type) CharAt(uint32_t aPos) const
486   {
487     NS_ASSERTION(aPos < Length(), "Out of bounds");
488     return BeginReading()[aPos];
489   }
NS_HIDDEN_(char_type)490   NS_HIDDEN_(char_type) operator [](uint32_t aPos) const
491   {
492     return CharAt(aPos);
493   }
First()494   NS_HIDDEN_(char_type) First() const
495   {
496     return CharAt(0);
497   }
Last()498   NS_HIDDEN_(char_type) Last() const
499   {
500     const char_type* data;
501     uint32_t dataLen = NS_CStringGetData(*this, &data);
502     return data[dataLen - 1];
503   }
504 
505   /**
506    * Get the length, begin writing, and optionally set the length of a
507    * string all in one operation.
508    *
509    * @param   newSize Size the string to this length. Pass UINT32_MAX
510    *                  to leave the length unchanged.
511    * @return  The new length of the string, or 0 if resizing failed.
512    */
513   NS_HIDDEN_(uint32_t) BeginWriting(char_type** aBegin,
514                                     char_type** aEnd = nullptr,
515                                     uint32_t aNewSize = UINT32_MAX);
516 
517   NS_HIDDEN_(char_type*) BeginWriting(uint32_t aLen = UINT32_MAX);
518   NS_HIDDEN_(char_type*) EndWriting();
519 
520   NS_HIDDEN_(bool) SetLength(uint32_t aLen);
521 
Length()522   NS_HIDDEN_(size_type) Length() const
523   {
524     const char_type* data;
525     return NS_CStringGetData(*this, &data);
526   }
527 
IsEmpty()528   NS_HIDDEN_(bool) IsEmpty() const { return Length() == 0; }
529 
SetIsVoid(bool aVal)530   NS_HIDDEN_(void) SetIsVoid(bool aVal) { NS_CStringSetIsVoid(*this, aVal); }
IsVoid()531   NS_HIDDEN_(bool) IsVoid() const { return NS_CStringGetIsVoid(*this); }
532 
Assign(const self_type & aString)533   NS_HIDDEN_(void) Assign(const self_type& aString)
534   {
535     NS_CStringCopy(*this, aString);
536   }
537   NS_HIDDEN_(void) Assign(const char_type* aData, size_type aLength = UINT32_MAX)
538   {
539     NS_CStringSetData(*this, aData, aLength);
540   }
Assign(char_type aChar)541   NS_HIDDEN_(void) Assign(char_type aChar)
542   {
543     NS_CStringSetData(*this, &aChar, 1);
544   }
AssignLiteral(const char_type * aData)545   NS_HIDDEN_(void) AssignLiteral(const char_type* aData)
546   {
547     Assign(aData);
548   }
AssignASCII(const char_type * aData)549   NS_HIDDEN_(void) AssignASCII(const char_type* aData)
550   {
551     Assign(aData);
552   }
553 
NS_HIDDEN_(self_type &)554   NS_HIDDEN_(self_type&) operator=(const self_type& aString)
555   {
556     Assign(aString);
557     return *this;
558   }
NS_HIDDEN_(self_type &)559   NS_HIDDEN_(self_type&) operator=(const char_type* aPtr)
560   {
561     Assign(aPtr);
562     return *this;
563   }
NS_HIDDEN_(self_type &)564   NS_HIDDEN_(self_type&) operator=(char_type aChar)
565   {
566     Assign(aChar);
567     return *this;
568   }
569 
570   NS_HIDDEN_(void) Replace(index_type aCutStart, size_type aCutLength,
571                            const char_type* aData,
572                            size_type aLength = size_type(-1))
573   {
574     NS_CStringSetDataRange(*this, aCutStart, aCutLength, aData, aLength);
575   }
Replace(index_type aCutStart,size_type aCutLength,char_type aChar)576   NS_HIDDEN_(void) Replace(index_type aCutStart, size_type aCutLength,
577                            char_type aChar)
578   {
579     Replace(aCutStart, aCutLength, &aChar, 1);
580   }
Replace(index_type aCutStart,size_type aCutLength,const self_type & aReadable)581   NS_HIDDEN_(void) Replace(index_type aCutStart, size_type aCutLength,
582                            const self_type& aReadable)
583   {
584     const char_type* data;
585     uint32_t dataLen = NS_CStringGetData(aReadable, &data);
586     NS_CStringSetDataRange(*this, aCutStart, aCutLength, data, dataLen);
587   }
SetCharAt(char_type aChar,index_type aPos)588   NS_HIDDEN_(void) SetCharAt(char_type aChar, index_type aPos)
589   {
590     Replace(aPos, 1, &aChar, 1);
591   }
592 
Append(char_type aChar)593   NS_HIDDEN_(void) Append(char_type aChar)
594   {
595     Replace(size_type(-1), 0, aChar);
596   }
597   NS_HIDDEN_(void) Append(const char_type* aData,
598                           size_type aLength = size_type(-1))
599   {
600     Replace(size_type(-1), 0, aData, aLength);
601   }
Append(const self_type & aReadable)602   NS_HIDDEN_(void) Append(const self_type& aReadable)
603   {
604     Replace(size_type(-1), 0, aReadable);
605   }
AppendLiteral(const char * aASCIIStr)606   NS_HIDDEN_(void) AppendLiteral(const char* aASCIIStr)
607   {
608     Append(aASCIIStr);
609   }
AppendASCII(const char * aASCIIStr)610   NS_HIDDEN_(void) AppendASCII(const char* aASCIIStr)
611   {
612     Append(aASCIIStr);
613   }
614 
615   NS_HIDDEN_(self_type&) operator+=(char_type aChar)
616   {
617     Append(aChar);
618     return *this;
619   }
620   NS_HIDDEN_(self_type&) operator+=(const char_type* aData)
621   {
622     Append(aData);
623     return *this;
624   }
625   NS_HIDDEN_(self_type&) operator+=(const self_type& aReadable)
626   {
627     Append(aReadable);
628     return *this;
629   }
630 
Insert(char_type aChar,index_type aPos)631   NS_HIDDEN_(void) Insert(char_type aChar, index_type aPos)
632   {
633     Replace(aPos, 0, aChar);
634   }
635   NS_HIDDEN_(void) Insert(const char_type* aData, index_type aPos,
636                           size_type aLength = size_type(-1))
637   {
638     Replace(aPos, 0, aData, aLength);
639   }
Insert(const self_type & aReadable,index_type aPos)640   NS_HIDDEN_(void) Insert(const self_type& aReadable, index_type aPos)
641   {
642     Replace(aPos, 0, aReadable);
643   }
644 
Cut(index_type aCutStart,size_type aCutLength)645   NS_HIDDEN_(void) Cut(index_type aCutStart, size_type aCutLength)
646   {
647     Replace(aCutStart, aCutLength, nullptr, 0);
648   }
649 
650   NS_HIDDEN_(void) Truncate(size_type aNewLength = 0)
651   {
652     NS_ASSERTION(aNewLength <= Length(), "Truncate cannot make string longer");
653     SetLength(aNewLength);
654   }
655 
656   /**
657    * Remove all occurences of characters in aSet from the string.
658    */
659   NS_HIDDEN_(void) StripChars(const char* aSet);
660 
661   /**
662    * Strip whitespace characters from the string.
663    */
StripWhitespace()664   NS_HIDDEN_(void) StripWhitespace() { StripChars("\b\t\r\n "); }
665 
666   NS_HIDDEN_(void) Trim(const char* aSet, bool aLeading = true,
667                         bool aTrailing = true);
668 
669   /**
670    * Compare strings of characters. Return 0 if the characters are equal,
671    */
672   typedef int32_t (*ComparatorFunc)(const char_type* a,
673                                     const char_type* b,
674                                     uint32_t length);
675 
676   static NS_HIDDEN_(int32_t) DefaultComparator(const char_type* aStrA,
677                                                const char_type* aStrB,
678                                                uint32_t aLength);
679 
680   NS_HIDDEN_(int32_t) Compare(const char_type* aOther,
681                               ComparatorFunc aComparator = DefaultComparator) const;
682 
683   NS_HIDDEN_(int32_t) Compare(const self_type& aOther,
684                               ComparatorFunc aComparator = DefaultComparator) const;
685 
686   NS_HIDDEN_(bool) Equals(const char_type* aOther,
687                           ComparatorFunc aComparator = DefaultComparator) const;
688 
689   NS_HIDDEN_(bool) Equals(const self_type& aOther,
690                           ComparatorFunc aComparator = DefaultComparator) const;
691 
692   NS_HIDDEN_(bool) operator<(const self_type& aOther) const
693   {
694     return Compare(aOther) < 0;
695   }
696   NS_HIDDEN_(bool) operator<(const char_type* aOther) const
697   {
698     return Compare(aOther) < 0;
699   }
700 
701   NS_HIDDEN_(bool) operator<=(const self_type& aOther) const
702   {
703     return Compare(aOther) <= 0;
704   }
705   NS_HIDDEN_(bool) operator<=(const char_type* aOther) const
706   {
707     return Compare(aOther) <= 0;
708   }
709 
710   NS_HIDDEN_(bool) operator==(const self_type& aOther) const
711   {
712     return Equals(aOther);
713   }
714   NS_HIDDEN_(bool) operator==(const char_type* aOther) const
715   {
716     return Equals(aOther);
717   }
718 
NS_HIDDEN_(bool)719   NS_HIDDEN_(bool) operator>=(const self_type& aOther) const
720   {
721     return Compare(aOther) >= 0;
722   }
NS_HIDDEN_(bool)723   NS_HIDDEN_(bool) operator>=(const char_type* aOther) const
724   {
725     return Compare(aOther) >= 0;
726   }
727 
NS_HIDDEN_(bool)728   NS_HIDDEN_(bool) operator>(const self_type& aOther) const
729   {
730     return Compare(aOther) > 0;
731   }
NS_HIDDEN_(bool)732   NS_HIDDEN_(bool) operator>(const char_type* aOther) const
733   {
734     return Compare(aOther) > 0;
735   }
736 
737   NS_HIDDEN_(bool) operator!=(const self_type& aOther) const
738   {
739     return !Equals(aOther);
740   }
741   NS_HIDDEN_(bool) operator!=(const char_type* aOther) const
742   {
743     return !Equals(aOther);
744   }
745 
EqualsLiteral(const char_type * aOther)746   NS_HIDDEN_(bool) EqualsLiteral(const char_type* aOther) const
747   {
748     return Equals(aOther);
749   }
EqualsASCII(const char_type * aOther)750   NS_HIDDEN_(bool) EqualsASCII(const char_type* aOther) const
751   {
752     return Equals(aOther);
753   }
754 
755   /**
756    * Case-insensitive match this string to a lowercase ASCII string.
757    */
LowerCaseEqualsLiteral(const char * aASCIIString)758   NS_HIDDEN_(bool) LowerCaseEqualsLiteral(const char* aASCIIString) const
759   {
760     return Equals(aASCIIString, CaseInsensitiveCompare);
761   }
762 
763   /**
764    * Find the first occurrence of aStr in this string.
765    *
766    * @return the offset of aStr, or -1 if not found
767    */
768   NS_HIDDEN_(int32_t) Find(const self_type& aStr,
769                            ComparatorFunc aComparator = DefaultComparator) const
770   {
771     return Find(aStr, 0, aComparator);
772   }
773 
774   /**
775    * Find the first occurrence of aStr in this string, beginning at aOffset.
776    *
777    * @return the offset of aStr, or -1 if not found
778    */
779   NS_HIDDEN_(int32_t) Find(const self_type& aStr, uint32_t aOffset,
780                            ComparatorFunc aComparator = DefaultComparator) const;
781 
782   /**
783    * Find the first occurrence of aStr in this string.
784    *
785    * @return the offset of aStr, or -1 if not found
786    */
787   NS_HIDDEN_(int32_t) Find(const char_type* aStr,
788                            ComparatorFunc aComparator = DefaultComparator) const;
789 
790   NS_HIDDEN_(int32_t) Find(const char_type* aStr, uint32_t aLen,
791                            ComparatorFunc aComparator = DefaultComparator) const;
792 
793   /**
794    * Find the last occurrence of aStr in this string.
795    *
796    * @return The offset of the character from the beginning of the string,
797    *         or -1 if not found.
798    */
799   NS_HIDDEN_(int32_t) RFind(const self_type& aStr,
800                             ComparatorFunc aComparator = DefaultComparator) const
801   {
802     return RFind(aStr, -1, aComparator);
803   }
804 
805   /**
806    * Find the last occurrence of aStr in this string, beginning at aOffset.
807    *
808    * @param aOffset the offset from the beginning of the string to begin
809    *        searching. If aOffset < 0, search from end of this string.
810    * @return The offset of aStr from the beginning of the string,
811    *         or -1 if not found.
812    */
813   NS_HIDDEN_(int32_t) RFind(const self_type& aStr, int32_t aOffset,
814                             ComparatorFunc aComparator = DefaultComparator) const;
815 
816   /**
817    * Find the last occurrence of aStr in this string.
818    *
819    * @return The offset of aStr from the beginning of the string,
820    *         or -1 if not found.
821    */
822   NS_HIDDEN_(int32_t) RFind(const char_type* aStr,
823                             ComparatorFunc aComparator = DefaultComparator) const;
824 
825   /**
826    * Find the last occurrence of an ASCII string in this string,
827    * beginning at aOffset.
828    *
829    * @param aLen is the length of aStr
830    * @return The offset of aStr from the beginning of the string,
831    *         or -1 if not found.
832    */
833   NS_HIDDEN_(int32_t) RFind(const char_type* aStr, int32_t aLen,
834                             ComparatorFunc aComparator = DefaultComparator) const;
835 
836   /**
837    * Search for the offset of the first occurrence of a character in a
838    * string.
839    *
840    * @param aOffset the offset from the beginning of the string to begin
841    *        searching
842    * @return The offset of the character from the beginning of the string,
843    *         or -1 if not found.
844    */
845   NS_HIDDEN_(int32_t) FindChar(char_type aChar, uint32_t aOffset = 0) const;
846 
847   /**
848    * Search for the offset of the last occurrence of a character in a
849    * string.
850    *
851    * @return The offset of the character from the beginning of the string,
852    *         or -1 if not found.
853    */
854   NS_HIDDEN_(int32_t) RFindChar(char_type aChar) const;
855 
856   /**
857    * Append a string representation of a number.
858    */
859   NS_HIDDEN_(void) AppendInt(int aInt, int32_t aRadix = 10);
860 
861 #ifndef XPCOM_GLUE_AVOID_NSPR
862   /**
863    * Convert this string to an integer.
864    *
865    * @param aErrorCode pointer to contain result code.
866    * @param aRadix must be 10 or 16
867    */
868   NS_HIDDEN_(int32_t) ToInteger(nsresult* aErrorCode,
869                                 uint32_t aRadix = 10) const;
870   /**
871    * Convert this string to a 64-bit integer.
872    *
873    * @param aErrorCode pointer to contain result code.
874    * @param aRadix must be 10 or 16
875    */
876   NS_HIDDEN_(int64_t) ToInteger64(nsresult* aErrorCode,
877                                   uint32_t aRadix = 10) const;
878 #endif // XPCOM_GLUE_AVOID_NSPR
879 
880 protected:
881   // Prevent people from allocating a nsAString directly.
~nsACString()882   ~nsACString() {}
883 };
884 
885 /* ------------------------------------------------------------------------- */
886 
887 /**
888  * Below we define nsStringContainer and nsCStringContainer.  These classes
889  * have unspecified structure.  In most cases, your code should use
890  * nsString/nsCString instead of these classes; if you prefer C-style
891  * programming, then look no further.
892  */
893 
894 class nsStringContainer
895   : public nsAString
896   , private nsStringContainer_base
897 {
898 };
899 
900 class nsCStringContainer
901   : public nsACString
902   , private nsStringContainer_base
903 {
904 };
905 
906 /**
907  * The following classes are C++ helper classes that make the frozen string
908  * API easier to use.
909  */
910 
911 /**
912  * Rename symbols to avoid conflicting with internal versions.
913  */
914 #define nsString                       nsString_external
915 #define nsCString                      nsCString_external
916 #define nsDependentString              nsDependentString_external
917 #define nsDependentCString             nsDependentCString_external
918 #define NS_ConvertASCIItoUTF16         NS_ConvertASCIItoUTF16_external
919 #define NS_ConvertUTF8toUTF16          NS_ConvertUTF8toUTF16_external
920 #define NS_ConvertUTF16toUTF8          NS_ConvertUTF16toUTF8_external
921 #define NS_LossyConvertUTF16toASCII    NS_LossyConvertUTF16toASCII_external
922 #define nsGetterCopies                 nsGetterCopies_external
923 #define nsCGetterCopies                nsCGetterCopies_external
924 #define nsDependentSubstring           nsDependentSubstring_external
925 #define nsDependentCSubstring          nsDependentCSubstring_external
926 
927 /**
928  * basic strings
929  */
930 
931 class nsString : public nsStringContainer
932 {
933 public:
934   typedef nsString         self_type;
935   typedef nsAString        abstract_string_type;
936 
nsString()937   nsString()
938   {
939     NS_StringContainerInit(*this);
940   }
941 
nsString(const self_type & aString)942   nsString(const self_type& aString)
943   {
944     NS_StringContainerInit(*this);
945     NS_StringCopy(*this, aString);
946   }
947 
nsString(const abstract_string_type & aReadable)948   explicit nsString(const abstract_string_type& aReadable)
949   {
950     NS_StringContainerInit(*this);
951     NS_StringCopy(*this, aReadable);
952   }
953 
954   explicit nsString(const char_type* aData, size_type aLength = UINT32_MAX)
955   {
956     NS_StringContainerInit2(*this, aData, aLength, 0);
957   }
958 
959 #ifdef MOZ_USE_CHAR16_WRAPPER
960   explicit nsString(char16ptr_t aData, size_type aLength = UINT32_MAX)
nsString(static_cast<const char16_t * > (aData),aLength)961     : nsString(static_cast<const char16_t*>(aData), aLength)
962   {
963   }
964 #endif
965 
~nsString()966   ~nsString()
967   {
968     NS_StringContainerFinish(*this);
969   }
970 
get()971   char16ptr_t get() const
972   {
973     return char16ptr_t(BeginReading());
974   }
975 
976   self_type& operator=(const self_type& aString)
977   {
978     Assign(aString);
979     return *this;
980   }
981   self_type& operator=(const abstract_string_type& aReadable)
982   {
983     Assign(aReadable);
984     return *this;
985   }
986   self_type& operator=(const char_type* aPtr)
987   {
988     Assign(aPtr);
989     return *this;
990   }
991   self_type& operator=(char_type aChar)
992   {
993     Assign(aChar);
994     return *this;
995   }
996 
997   void Adopt(const char_type* aData, size_type aLength = UINT32_MAX)
998   {
999     NS_StringContainerFinish(*this);
1000     NS_StringContainerInit2(*this, aData, aLength,
1001                             NS_STRING_CONTAINER_INIT_ADOPT);
1002   }
1003 
1004 protected:
nsString(const char_type * aData,size_type aLength,uint32_t aFlags)1005   nsString(const char_type* aData, size_type aLength, uint32_t aFlags)
1006   {
1007     NS_StringContainerInit2(*this, aData, aLength, aFlags);
1008   }
1009 };
1010 
1011 class nsCString : public nsCStringContainer
1012 {
1013 public:
1014   typedef nsCString        self_type;
1015   typedef nsACString       abstract_string_type;
1016 
nsCString()1017   nsCString()
1018   {
1019     NS_CStringContainerInit(*this);
1020   }
1021 
nsCString(const self_type & aString)1022   nsCString(const self_type& aString)
1023   {
1024     NS_CStringContainerInit(*this);
1025     NS_CStringCopy(*this, aString);
1026   }
1027 
nsCString(const abstract_string_type & aReadable)1028   explicit nsCString(const abstract_string_type& aReadable)
1029   {
1030     NS_CStringContainerInit(*this);
1031     NS_CStringCopy(*this, aReadable);
1032   }
1033 
1034   explicit nsCString(const char_type* aData, size_type aLength = UINT32_MAX)
1035   {
1036     NS_CStringContainerInit(*this);
1037     NS_CStringSetData(*this, aData, aLength);
1038   }
1039 
~nsCString()1040   ~nsCString()
1041   {
1042     NS_CStringContainerFinish(*this);
1043   }
1044 
get()1045   const char_type* get() const
1046   {
1047     return BeginReading();
1048   }
1049 
1050   self_type& operator=(const self_type& aString)
1051   {
1052     Assign(aString);
1053     return *this;
1054   }
1055   self_type& operator=(const abstract_string_type& aReadable)
1056   {
1057     Assign(aReadable);
1058     return *this;
1059   }
1060   self_type& operator=(const char_type* aPtr)
1061   {
1062     Assign(aPtr);
1063     return *this;
1064   }
1065   self_type& operator=(char_type aChar)
1066   {
1067     Assign(aChar);
1068     return *this;
1069   }
1070 
1071   void Adopt(const char_type* aData, size_type aLength = UINT32_MAX)
1072   {
1073     NS_CStringContainerFinish(*this);
1074     NS_CStringContainerInit2(*this, aData, aLength,
1075                              NS_CSTRING_CONTAINER_INIT_ADOPT);
1076   }
1077 
1078 protected:
nsCString(const char_type * aData,size_type aLength,uint32_t aFlags)1079   nsCString(const char_type* aData, size_type aLength, uint32_t aFlags)
1080   {
1081     NS_CStringContainerInit2(*this, aData, aLength, aFlags);
1082   }
1083 };
1084 
1085 
1086 /**
1087  * dependent strings
1088  */
1089 
1090 class nsDependentString : public nsString
1091 {
1092 public:
1093   typedef nsDependentString         self_type;
1094 
nsDependentString()1095   nsDependentString() {}
1096 
1097   explicit nsDependentString(const char_type* aData,
1098                              size_type aLength = UINT32_MAX)
nsString(aData,aLength,NS_CSTRING_CONTAINER_INIT_DEPEND)1099     : nsString(aData, aLength, NS_CSTRING_CONTAINER_INIT_DEPEND)
1100   {
1101   }
1102 
1103 #ifdef MOZ_USE_CHAR16_WRAPPER
1104   explicit nsDependentString(char16ptr_t aData, size_type aLength = UINT32_MAX)
nsDependentString(static_cast<const char16_t * > (aData),aLength)1105     : nsDependentString(static_cast<const char16_t*>(aData), aLength)
1106   {
1107   }
1108 #endif
1109 
1110   void Rebind(const char_type* aData, size_type aLength = UINT32_MAX)
1111   {
1112     NS_StringContainerFinish(*this);
1113     NS_StringContainerInit2(*this, aData, aLength,
1114                             NS_STRING_CONTAINER_INIT_DEPEND);
1115   }
1116 
1117 private:
1118   self_type& operator=(const self_type& aString) = delete;
1119 };
1120 
1121 class nsDependentCString : public nsCString
1122 {
1123 public:
1124   typedef nsDependentCString        self_type;
1125 
nsDependentCString()1126   nsDependentCString() {}
1127 
1128   explicit nsDependentCString(const char_type* aData,
1129                               size_type aLength = UINT32_MAX)
nsCString(aData,aLength,NS_CSTRING_CONTAINER_INIT_DEPEND)1130     : nsCString(aData, aLength, NS_CSTRING_CONTAINER_INIT_DEPEND)
1131   {
1132   }
1133 
1134   void Rebind(const char_type* aData, size_type aLength = UINT32_MAX)
1135   {
1136     NS_CStringContainerFinish(*this);
1137     NS_CStringContainerInit2(*this, aData, aLength,
1138                              NS_CSTRING_CONTAINER_INIT_DEPEND);
1139   }
1140 
1141 private:
1142   self_type& operator=(const self_type& aString) = delete;
1143 };
1144 
1145 
1146 /**
1147  * conversion classes
1148  */
1149 
1150 inline void
CopyUTF16toUTF8(const nsAString & aSource,nsACString & aDest)1151 CopyUTF16toUTF8(const nsAString& aSource, nsACString& aDest)
1152 {
1153   NS_UTF16ToCString(aSource, NS_CSTRING_ENCODING_UTF8, aDest);
1154 }
1155 
1156 inline void
CopyUTF8toUTF16(const nsACString & aSource,nsAString & aDest)1157 CopyUTF8toUTF16(const nsACString& aSource, nsAString& aDest)
1158 {
1159   NS_CStringToUTF16(aSource, NS_CSTRING_ENCODING_UTF8, aDest);
1160 }
1161 
1162 inline void
LossyCopyUTF16toASCII(const nsAString & aSource,nsACString & aDest)1163 LossyCopyUTF16toASCII(const nsAString& aSource, nsACString& aDest)
1164 {
1165   NS_UTF16ToCString(aSource, NS_CSTRING_ENCODING_ASCII, aDest);
1166 }
1167 
1168 inline void
CopyASCIItoUTF16(const nsACString & aSource,nsAString & aDest)1169 CopyASCIItoUTF16(const nsACString& aSource, nsAString& aDest)
1170 {
1171   NS_CStringToUTF16(aSource, NS_CSTRING_ENCODING_ASCII, aDest);
1172 }
1173 
1174 char*
1175 ToNewUTF8String(const nsAString& aSource);
1176 
1177 class NS_ConvertASCIItoUTF16 : public nsString
1178 {
1179 public:
1180   typedef NS_ConvertASCIItoUTF16    self_type;
1181 
NS_ConvertASCIItoUTF16(const nsACString & aStr)1182   explicit NS_ConvertASCIItoUTF16(const nsACString& aStr)
1183   {
1184     NS_CStringToUTF16(aStr, NS_CSTRING_ENCODING_ASCII, *this);
1185   }
1186 
1187   explicit NS_ConvertASCIItoUTF16(const char* aData,
1188                                   uint32_t aLength = UINT32_MAX)
1189   {
1190     NS_CStringToUTF16(nsDependentCString(aData, aLength),
1191                       NS_CSTRING_ENCODING_ASCII, *this);
1192   }
1193 
1194 private:
1195   self_type& operator=(const self_type& aString) = delete;
1196 };
1197 
1198 class NS_ConvertUTF8toUTF16 : public nsString
1199 {
1200 public:
1201   typedef NS_ConvertUTF8toUTF16    self_type;
1202 
NS_ConvertUTF8toUTF16(const nsACString & aStr)1203   explicit NS_ConvertUTF8toUTF16(const nsACString& aStr)
1204   {
1205     NS_CStringToUTF16(aStr, NS_CSTRING_ENCODING_UTF8, *this);
1206   }
1207 
1208   explicit NS_ConvertUTF8toUTF16(const char* aData,
1209                                  uint32_t aLength = UINT32_MAX)
1210   {
1211     NS_CStringToUTF16(nsDependentCString(aData, aLength),
1212                       NS_CSTRING_ENCODING_UTF8, *this);
1213   }
1214 
1215 private:
1216   self_type& operator=(const self_type& aString) = delete;
1217 };
1218 
1219 class NS_ConvertUTF16toUTF8 : public nsCString
1220 {
1221 public:
1222   typedef NS_ConvertUTF16toUTF8    self_type;
1223 
NS_ConvertUTF16toUTF8(const nsAString & aStr)1224   explicit NS_ConvertUTF16toUTF8(const nsAString& aStr)
1225   {
1226     NS_UTF16ToCString(aStr, NS_CSTRING_ENCODING_UTF8, *this);
1227   }
1228 
1229   explicit NS_ConvertUTF16toUTF8(const char16ptr_t aData,
1230                                  uint32_t aLength = UINT32_MAX)
1231   {
1232     NS_UTF16ToCString(nsDependentString(aData, aLength),
1233                       NS_CSTRING_ENCODING_UTF8, *this);
1234   }
1235 
1236 private:
1237   self_type& operator=(const self_type& aString) = delete;
1238 };
1239 
1240 class NS_LossyConvertUTF16toASCII : public nsCString
1241 {
1242 public:
1243   typedef NS_LossyConvertUTF16toASCII    self_type;
1244 
NS_LossyConvertUTF16toASCII(const nsAString & aStr)1245   explicit NS_LossyConvertUTF16toASCII(const nsAString& aStr)
1246   {
1247     NS_UTF16ToCString(aStr, NS_CSTRING_ENCODING_ASCII, *this);
1248   }
1249 
1250   explicit NS_LossyConvertUTF16toASCII(const char16ptr_t aData,
1251                                        uint32_t aLength = UINT32_MAX)
1252   {
1253     NS_UTF16ToCString(nsDependentString(aData, aLength),
1254                       NS_CSTRING_ENCODING_ASCII, *this);
1255   }
1256 
1257 private:
1258   self_type& operator=(const self_type& aString) = delete;
1259 };
1260 
1261 
1262 /**
1263  * literal strings
1264  */
1265 static_assert(sizeof(char16_t) == 2, "size of char16_t must be 2");
1266 static_assert(char16_t(-1) > char16_t(0), "char16_t must be unsigned");
1267 
1268 #define NS_MULTILINE_LITERAL_STRING(s) \
1269   nsDependentString(reinterpret_cast<const nsAString::char_type*>(s), \
1270                     uint32_t((sizeof(s) / 2) - 1))
1271 #define NS_MULTILINE_LITERAL_STRING_INIT(n, s) \
1272   n(reinterpret_cast<const nsAString::char_type*>(s), \
1273     uint32_t((sizeof(s) / 2) - 1))
1274 #define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) \
1275   const nsDependentString n(reinterpret_cast<const nsAString::char_type*>(s), \
1276                             uint32_t((sizeof(s) / 2) - 1))
1277 typedef nsDependentString nsLiteralString;
1278 
1279 #define NS_LITERAL_STRING(s) \
1280   static_cast<const nsString&>(NS_MULTILINE_LITERAL_STRING(u"" s))
1281 #define NS_LITERAL_STRING_INIT(n, s) \
1282   NS_MULTILINE_LITERAL_STRING_INIT(n, (u"" s))
1283 #define NS_NAMED_LITERAL_STRING(n, s) \
1284   NS_NAMED_MULTILINE_LITERAL_STRING(n, (u"" s))
1285 
1286 #define NS_LITERAL_CSTRING(s) \
1287   static_cast<const nsDependentCString&>(nsDependentCString(s, uint32_t(sizeof(s) - 1)))
1288 #define NS_LITERAL_CSTRING_INIT(n, s) \
1289   n(s, uint32_t(sizeof(s)-1))
1290 #define NS_NAMED_LITERAL_CSTRING(n, s) \
1291   const nsDependentCString n(s, uint32_t(sizeof(s)-1))
1292 
1293 typedef nsDependentCString nsLiteralCString;
1294 
1295 
1296 /**
1297  * getter_Copies support
1298  *
1299  *    NS_IMETHOD GetBlah(char16_t**);
1300  *
1301  *    void some_function()
1302  *    {
1303  *      nsString blah;
1304  *      GetBlah(getter_Copies(blah));
1305  *      // ...
1306  *    }
1307  */
1308 
1309 class nsGetterCopies
1310 {
1311 public:
1312   typedef char16_t char_type;
1313 
nsGetterCopies(nsString & aStr)1314   explicit nsGetterCopies(nsString& aStr)
1315     : mString(aStr)
1316     , mData(nullptr)
1317   {
1318   }
1319 
~nsGetterCopies()1320   ~nsGetterCopies() { mString.Adopt(mData); }
1321 
1322   operator char_type**() { return &mData; }
1323 
1324 private:
1325   nsString&  mString;
1326   char_type* mData;
1327 };
1328 
1329 inline nsGetterCopies
getter_Copies(nsString & aString)1330 getter_Copies(nsString& aString)
1331 {
1332   return nsGetterCopies(aString);
1333 }
1334 
1335 class nsCGetterCopies
1336 {
1337 public:
1338   typedef char char_type;
1339 
nsCGetterCopies(nsCString & aStr)1340   explicit nsCGetterCopies(nsCString& aStr)
1341     : mString(aStr)
1342     , mData(nullptr)
1343   {
1344   }
1345 
~nsCGetterCopies()1346   ~nsCGetterCopies() { mString.Adopt(mData); }
1347 
1348   operator char_type**() { return &mData; }
1349 
1350 private:
1351   nsCString& mString;
1352   char_type* mData;
1353 };
1354 
1355 inline nsCGetterCopies
getter_Copies(nsCString & aString)1356 getter_Copies(nsCString& aString)
1357 {
1358   return nsCGetterCopies(aString);
1359 }
1360 
1361 
1362 /**
1363 * substrings
1364 */
1365 
1366 class nsDependentSubstring : public nsStringContainer
1367 {
1368 public:
1369   typedef nsDependentSubstring self_type;
1370   typedef nsAString            abstract_string_type;
1371 
~nsDependentSubstring()1372   ~nsDependentSubstring() { NS_StringContainerFinish(*this); }
nsDependentSubstring()1373   nsDependentSubstring() { NS_StringContainerInit(*this); }
1374 
nsDependentSubstring(const char_type * aStart,uint32_t aLength)1375   nsDependentSubstring(const char_type* aStart, uint32_t aLength)
1376   {
1377     NS_StringContainerInit2(*this, aStart, aLength,
1378                             NS_STRING_CONTAINER_INIT_DEPEND |
1379                             NS_STRING_CONTAINER_INIT_SUBSTRING);
1380   }
1381 
1382   nsDependentSubstring(const abstract_string_type& aStr,
1383                        uint32_t aStartPos);
1384   nsDependentSubstring(const abstract_string_type& aStr,
1385                        uint32_t aStartPos, uint32_t aLength);
1386 
Rebind(const char_type * aStart,uint32_t aLength)1387   void Rebind(const char_type* aStart, uint32_t aLength)
1388   {
1389     NS_StringContainerFinish(*this);
1390     NS_StringContainerInit2(*this, aStart, aLength,
1391                             NS_STRING_CONTAINER_INIT_DEPEND |
1392                             NS_STRING_CONTAINER_INIT_SUBSTRING);
1393   }
1394 
1395 private:
1396   self_type& operator=(const self_type& aString) = delete;
1397 };
1398 
1399 class nsDependentCSubstring : public nsCStringContainer
1400 {
1401 public:
1402   typedef nsDependentCSubstring self_type;
1403   typedef nsACString            abstract_string_type;
1404 
~nsDependentCSubstring()1405   ~nsDependentCSubstring() { NS_CStringContainerFinish(*this); }
nsDependentCSubstring()1406   nsDependentCSubstring() { NS_CStringContainerInit(*this); }
1407 
nsDependentCSubstring(const char_type * aStart,uint32_t aLength)1408   nsDependentCSubstring(const char_type* aStart, uint32_t aLength)
1409   {
1410     NS_CStringContainerInit2(*this, aStart, aLength,
1411                              NS_CSTRING_CONTAINER_INIT_DEPEND |
1412                              NS_CSTRING_CONTAINER_INIT_SUBSTRING);
1413   }
1414 
1415   nsDependentCSubstring(const abstract_string_type& aStr,
1416                         uint32_t aStartPos);
1417   nsDependentCSubstring(const abstract_string_type& aStr,
1418                         uint32_t aStartPos, uint32_t aLength);
1419 
Rebind(const char_type * aStart,uint32_t aLength)1420   void Rebind(const char_type* aStart, uint32_t aLength)
1421   {
1422     NS_CStringContainerFinish(*this);
1423     NS_CStringContainerInit2(*this, aStart, aLength,
1424                              NS_CSTRING_CONTAINER_INIT_DEPEND |
1425                              NS_CSTRING_CONTAINER_INIT_SUBSTRING);
1426   }
1427 
1428 private:
1429   self_type& operator=(const self_type& aString) = delete;
1430 };
1431 
1432 
1433 /**
1434  * Various nsDependentC?Substring constructor functions
1435  */
1436 
1437 // char16_t
1438 inline const nsDependentSubstring
Substring(const nsAString & aStr,uint32_t aStartPos)1439 Substring(const nsAString& aStr, uint32_t aStartPos)
1440 {
1441   return nsDependentSubstring(aStr, aStartPos);
1442 }
1443 
1444 inline const nsDependentSubstring
Substring(const nsAString & aStr,uint32_t aStartPos,uint32_t aLength)1445 Substring(const nsAString& aStr, uint32_t aStartPos, uint32_t aLength)
1446 {
1447   return nsDependentSubstring(aStr, aStartPos, aLength);
1448 }
1449 
1450 inline const nsDependentSubstring
Substring(const char16_t * aStart,const char16_t * aEnd)1451 Substring(const char16_t* aStart, const char16_t* aEnd)
1452 {
1453   MOZ_ASSERT(uint32_t(aEnd - aStart) == uintptr_t(aEnd - aStart),
1454              "string too long");
1455   return nsDependentSubstring(aStart, uint32_t(aEnd - aStart));
1456 }
1457 
1458 inline const nsDependentSubstring
Substring(const char16_t * aStart,uint32_t aLength)1459 Substring(const char16_t* aStart, uint32_t aLength)
1460 {
1461   return nsDependentSubstring(aStart, aLength);
1462 }
1463 
1464 inline const nsDependentSubstring
StringHead(const nsAString & aStr,uint32_t aCount)1465 StringHead(const nsAString& aStr, uint32_t aCount)
1466 {
1467   return nsDependentSubstring(aStr, 0, aCount);
1468 }
1469 
1470 inline const nsDependentSubstring
StringTail(const nsAString & aStr,uint32_t aCount)1471 StringTail(const nsAString& aStr, uint32_t aCount)
1472 {
1473   return nsDependentSubstring(aStr, aStr.Length() - aCount, aCount);
1474 }
1475 
1476 // char
1477 inline const nsDependentCSubstring
Substring(const nsACString & aStr,uint32_t aStartPos)1478 Substring(const nsACString& aStr, uint32_t aStartPos)
1479 {
1480   return nsDependentCSubstring(aStr, aStartPos);
1481 }
1482 
1483 inline const nsDependentCSubstring
Substring(const nsACString & aStr,uint32_t aStartPos,uint32_t aLength)1484 Substring(const nsACString& aStr, uint32_t aStartPos, uint32_t aLength)
1485 {
1486   return nsDependentCSubstring(aStr, aStartPos, aLength);
1487 }
1488 
1489 inline const nsDependentCSubstring
Substring(const char * aStart,const char * aEnd)1490 Substring(const char* aStart, const char* aEnd)
1491 {
1492   MOZ_ASSERT(uint32_t(aEnd - aStart) == uintptr_t(aEnd - aStart),
1493              "string too long");
1494   return nsDependentCSubstring(aStart, uint32_t(aEnd - aStart));
1495 }
1496 
1497 inline const nsDependentCSubstring
Substring(const char * aStart,uint32_t aLength)1498 Substring(const char* aStart, uint32_t aLength)
1499 {
1500   return nsDependentCSubstring(aStart, aLength);
1501 }
1502 
1503 inline const nsDependentCSubstring
StringHead(const nsACString & aStr,uint32_t aCount)1504 StringHead(const nsACString& aStr, uint32_t aCount)
1505 {
1506   return nsDependentCSubstring(aStr, 0, aCount);
1507 }
1508 
1509 inline const nsDependentCSubstring
StringTail(const nsACString & aStr,uint32_t aCount)1510 StringTail(const nsACString& aStr, uint32_t aCount)
1511 {
1512   return nsDependentCSubstring(aStr, aStr.Length() - aCount, aCount);
1513 }
1514 
1515 
1516 inline bool
1517 StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
1518                  nsAString::ComparatorFunc aComparator = nsAString::DefaultComparator)
1519 {
1520   return aSubstring.Length() <= aSource.Length() &&
1521     StringHead(aSource, aSubstring.Length()).Equals(aSubstring, aComparator);
1522 }
1523 
1524 inline bool
1525 StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
1526                nsAString::ComparatorFunc aComparator = nsAString::DefaultComparator)
1527 {
1528   return aSubstring.Length() <= aSource.Length() &&
1529     StringTail(aSource, aSubstring.Length()).Equals(aSubstring, aComparator);
1530 }
1531 
1532 inline bool
1533 StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
1534                  nsACString::ComparatorFunc aComparator = nsACString::DefaultComparator)
1535 {
1536   return aSubstring.Length() <= aSource.Length() &&
1537     StringHead(aSource, aSubstring.Length()).Equals(aSubstring, aComparator);
1538 }
1539 
1540 inline bool
1541 StringEndsWith(const nsACString& aSource, const nsACString& aSubstring,
1542                nsACString::ComparatorFunc aComparator = nsACString::DefaultComparator)
1543 {
1544   return aSubstring.Length() <= aSource.Length() &&
1545     StringTail(aSource, aSubstring.Length()).Equals(aSubstring, aComparator);
1546 }
1547 
1548 /**
1549  * Trim whitespace from the beginning and end of a string; then compress
1550  * remaining runs of whitespace characters to a single space.
1551  */
1552 NS_HIDDEN_(void) CompressWhitespace(nsAString& aString);
1553 
1554 #define EmptyCString() nsCString()
1555 #define EmptyString() nsString()
1556 
1557 /**
1558  * Convert an ASCII string to all upper/lowercase (a-z,A-Z only). As a bonus,
1559  * returns the string length.
1560  */
1561 NS_HIDDEN_(uint32_t) ToLowerCase(nsACString& aStr);
1562 
1563 NS_HIDDEN_(uint32_t) ToUpperCase(nsACString& aStr);
1564 
1565 NS_HIDDEN_(uint32_t) ToLowerCase(const nsACString& aSrc, nsACString& aDest);
1566 
1567 NS_HIDDEN_(uint32_t) ToUpperCase(const nsACString& aSrc, nsACString& aDest);
1568 
1569 /**
1570  * The following declarations are *deprecated*, and are included here only
1571  * to make porting from existing code that doesn't use the frozen string API
1572  * easier. They may disappear in the future.
1573  */
1574 
1575 inline char*
ToNewCString(const nsACString & aStr)1576 ToNewCString(const nsACString& aStr)
1577 {
1578   return NS_CStringCloneData(aStr);
1579 }
1580 
1581 inline char16_t*
ToNewUnicode(const nsAString & aStr)1582 ToNewUnicode(const nsAString& aStr)
1583 {
1584   return NS_StringCloneData(aStr);
1585 }
1586 
1587 typedef nsString PromiseFlatString;
1588 typedef nsCString PromiseFlatCString;
1589 
1590 typedef nsCString nsAutoCString;
1591 typedef nsString nsAutoString;
1592 
1593 NS_HIDDEN_(bool) ParseString(const nsACString& aAstring, char aDelimiter,
1594                              nsTArray<nsCString>& aArray);
1595 
1596 #endif // nsStringAPI_h__
1597