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