Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 : // IWYU pragma: private, include "nsString.h"
7 :
8 : /**
9 : * This is the canonical null-terminated string class. All subclasses
10 : * promise null-terminated storage. Instances of this class allocate
11 : * strings on the heap.
12 : *
13 : * NAMES:
14 : * nsString for wide characters
15 : * nsCString for narrow characters
16 : *
17 : * This class is also known as nsAFlat[C]String, where "flat" is used
18 : * to denote a null-terminated string.
19 : */
20 539279 : class nsTString_CharT : public nsTSubstring_CharT
21 : {
22 : public:
23 :
24 : typedef nsTString_CharT self_type;
25 :
26 : public:
27 :
28 : /**
29 : * constructors
30 : */
31 :
32 191502 : nsTString_CharT()
33 191502 : : substring_type()
34 : {
35 191502 : }
36 :
37 : explicit
38 18007 : nsTString_CharT(const char_type* aData, size_type aLength = size_type(-1))
39 18007 : : substring_type()
40 : {
41 18007 : Assign(aData, aLength);
42 18007 : }
43 :
44 : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
45 : explicit
46 : nsTString_CharT(char16ptr_t aStr, size_type aLength = size_type(-1))
47 : : substring_type()
48 : {
49 : Assign(static_cast<const char16_t*>(aStr), aLength);
50 : }
51 : #endif
52 :
53 24641 : nsTString_CharT(const self_type& aStr)
54 24641 : : substring_type()
55 : {
56 24641 : Assign(aStr);
57 24641 : }
58 :
59 221 : MOZ_IMPLICIT nsTString_CharT(const substring_tuple_type& aTuple)
60 221 : : substring_type()
61 : {
62 221 : Assign(aTuple);
63 221 : }
64 :
65 : explicit
66 19970 : nsTString_CharT(const substring_type& aReadable)
67 19970 : : substring_type()
68 : {
69 19970 : Assign(aReadable);
70 19970 : }
71 :
72 :
73 : // |operator=| does not inherit, so we must define our own
74 0 : self_type& operator=(char_type aChar)
75 : {
76 0 : Assign(aChar);
77 0 : return *this;
78 : }
79 6239 : self_type& operator=(const char_type* aData)
80 : {
81 6239 : Assign(aData);
82 6239 : return *this;
83 : }
84 45938 : self_type& operator=(const self_type& aStr)
85 : {
86 45938 : Assign(aStr);
87 45938 : return *this;
88 : }
89 : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
90 : self_type& operator=(const char16ptr_t aStr)
91 : {
92 : Assign(static_cast<const char16_t*>(aStr));
93 : return *this;
94 : }
95 : #endif
96 12643 : self_type& operator=(const substring_type& aStr)
97 : {
98 12643 : Assign(aStr);
99 12643 : return *this;
100 : }
101 246 : self_type& operator=(const substring_tuple_type& aTuple)
102 : {
103 246 : Assign(aTuple);
104 246 : return *this;
105 : }
106 :
107 : /**
108 : * returns the null-terminated string
109 : */
110 :
111 : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
112 : char16ptr_t get() const
113 : #else
114 188799 : const char_type* get() const
115 : #endif
116 : {
117 188799 : return mData;
118 : }
119 :
120 :
121 : /**
122 : * returns character at specified index.
123 : *
124 : * NOTE: unlike nsTSubstring::CharAt, this function allows you to index
125 : * the null terminator character.
126 : */
127 :
128 30967 : char_type CharAt(index_type aIndex) const
129 : {
130 30967 : NS_ASSERTION(aIndex <= mLength, "index exceeds allowable range");
131 30967 : return mData[aIndex];
132 : }
133 :
134 27722 : char_type operator[](index_type aIndex) const
135 : {
136 27722 : return CharAt(aIndex);
137 : }
138 :
139 :
140 : #if MOZ_STRING_WITH_OBSOLETE_API
141 :
142 :
143 : /**
144 : * Search for the given substring within this string.
145 : *
146 : * @param aString is substring to be sought in this
147 : * @param aIgnoreCase selects case sensitivity
148 : * @param aOffset tells us where in this string to start searching
149 : * @param aCount tells us how far from the offset we are to search. Use
150 : * -1 to search the whole string.
151 : * @return offset in string, or kNotFound
152 : */
153 :
154 : int32_t Find(const nsCString& aString, bool aIgnoreCase = false,
155 : int32_t aOffset = 0, int32_t aCount = -1) const;
156 : int32_t Find(const char* aString, bool aIgnoreCase = false,
157 : int32_t aOffset = 0, int32_t aCount = -1) const;
158 :
159 : #ifdef CharT_is_PRUnichar
160 : int32_t Find(const nsString& aString, int32_t aOffset = 0,
161 : int32_t aCount = -1) const;
162 : int32_t Find(const char16_t* aString, int32_t aOffset = 0,
163 : int32_t aCount = -1) const;
164 : #ifdef MOZ_USE_CHAR16_WRAPPER
165 : int32_t Find(char16ptr_t aString, int32_t aOffset = 0,
166 : int32_t aCount = -1) const
167 : {
168 : return Find(static_cast<const char16_t*>(aString), aOffset, aCount);
169 : }
170 : #endif
171 : #endif
172 :
173 :
174 : /**
175 : * This methods scans the string backwards, looking for the given string
176 : *
177 : * @param aString is substring to be sought in this
178 : * @param aIgnoreCase tells us whether or not to do caseless compare
179 : * @param aOffset tells us where in this string to start searching.
180 : * Use -1 to search from the end of the string.
181 : * @param aCount tells us how many iterations to make starting at the
182 : * given offset.
183 : * @return offset in string, or kNotFound
184 : */
185 :
186 : int32_t RFind(const nsCString& aString, bool aIgnoreCase = false,
187 : int32_t aOffset = -1, int32_t aCount = -1) const;
188 : int32_t RFind(const char* aCString, bool aIgnoreCase = false,
189 : int32_t aOffset = -1, int32_t aCount = -1) const;
190 :
191 : #ifdef CharT_is_PRUnichar
192 : int32_t RFind(const nsString& aString, int32_t aOffset = -1,
193 : int32_t aCount = -1) const;
194 : int32_t RFind(const char16_t* aString, int32_t aOffset = -1,
195 : int32_t aCount = -1) const;
196 : #endif
197 :
198 :
199 : /**
200 : * Search for given char within this string
201 : *
202 : * @param aChar is the character to search for
203 : * @param aOffset tells us where in this string to start searching
204 : * @param aCount tells us how far from the offset we are to search.
205 : * Use -1 to search the whole string.
206 : * @return offset in string, or kNotFound
207 : */
208 :
209 : // int32_t FindChar( char16_t aChar, int32_t aOffset=0, int32_t aCount=-1 ) const;
210 : int32_t RFindChar(char16_t aChar, int32_t aOffset = -1,
211 : int32_t aCount = -1) const;
212 :
213 :
214 : /**
215 : * This method searches this string for the first character found in
216 : * the given string.
217 : *
218 : * @param aString contains set of chars to be found
219 : * @param aOffset tells us where in this string to start searching
220 : * (counting from left)
221 : * @return offset in string, or kNotFound
222 : */
223 :
224 : int32_t FindCharInSet(const char* aString, int32_t aOffset = 0) const;
225 79 : int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const
226 : {
227 79 : return FindCharInSet(aString.get(), aOffset);
228 : }
229 :
230 : #ifdef CharT_is_PRUnichar
231 : int32_t FindCharInSet(const char16_t* aString, int32_t aOffset = 0) const;
232 : #endif
233 :
234 :
235 : /**
236 : * This method searches this string for the last character found in
237 : * the given string.
238 : *
239 : * @param aString contains set of chars to be found
240 : * @param aOffset tells us where in this string to start searching
241 : * (counting from left)
242 : * @return offset in string, or kNotFound
243 : */
244 :
245 : int32_t RFindCharInSet(const char_type* aString, int32_t aOffset = -1) const;
246 : int32_t RFindCharInSet(const self_type& aString, int32_t aOffset = -1) const
247 : {
248 : return RFindCharInSet(aString.get(), aOffset);
249 : }
250 :
251 :
252 : /**
253 : * Compares a given string to this string.
254 : *
255 : * @param aString is the string to be compared
256 : * @param aIgnoreCase tells us how to treat case
257 : * @param aCount tells us how many chars to compare
258 : * @return -1,0,1
259 : */
260 :
261 : #ifdef CharT_is_char
262 : int32_t Compare(const char* aString, bool aIgnoreCase = false,
263 : int32_t aCount = -1) const;
264 : #endif
265 :
266 :
267 : /**
268 : * Equality check between given string and this string.
269 : *
270 : * @param aString is the string to check
271 : * @param aIgnoreCase tells us how to treat case
272 : * @param aCount tells us how many chars to compare
273 : * @return boolean
274 : */
275 : #ifdef CharT_is_char
276 2 : bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const
277 : {
278 2 : return Compare(aString, true, aCount) == 0;
279 : }
280 : #else
281 : bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const;
282 :
283 :
284 : #endif // !CharT_is_PRUnichar
285 :
286 : /**
287 : * Perform string to double-precision float conversion.
288 : *
289 : * @param aErrorCode will contain error if one occurs
290 : * @return double-precision float rep of string value
291 : */
292 : double ToDouble(nsresult* aErrorCode) const;
293 :
294 : /**
295 : * Perform string to single-precision float conversion.
296 : *
297 : * @param aErrorCode will contain error if one occurs
298 : * @return single-precision float rep of string value
299 : */
300 128 : float ToFloat(nsresult* aErrorCode) const
301 : {
302 128 : return (float)ToDouble(aErrorCode);
303 : }
304 :
305 :
306 : /**
307 : * Perform string to int conversion.
308 : * @param aErrorCode will contain error if one occurs
309 : * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
310 : * @return int rep of string value, and possible (out) error code
311 : */
312 : int32_t ToInteger(nsresult* aErrorCode, uint32_t aRadix = kRadix10) const;
313 :
314 : /**
315 : * Perform string to 64-bit int conversion.
316 : * @param aErrorCode will contain error if one occurs
317 : * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
318 : * @return 64-bit int rep of string value, and possible (out) error code
319 : */
320 : int64_t ToInteger64(nsresult* aErrorCode, uint32_t aRadix = kRadix10) const;
321 :
322 :
323 : /**
324 : * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
325 : * any _other_ way than they are now. Consider these alternatives
326 : *
327 : * aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
328 : * aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
329 : * Left(aReadable, 17, aWritable); // ...a global function that does the assignment
330 : *
331 : * as opposed to the current signature
332 : *
333 : * aReadable.Left(aWritable, 17); // ...a member function that does the assignment
334 : *
335 : * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
336 : *
337 : * aWritable = Substring(aReadable, 0, 17);
338 : */
339 :
340 : size_type Mid(self_type& aResult, uint32_t aStartPos, uint32_t aCount) const;
341 :
342 97 : size_type Left(self_type& aResult, size_type aCount) const
343 : {
344 97 : return Mid(aResult, 0, aCount);
345 : }
346 :
347 7 : size_type Right(self_type& aResult, size_type aCount) const
348 : {
349 7 : aCount = XPCOM_MIN(mLength, aCount);
350 7 : return Mid(aResult, mLength - aCount, aCount);
351 : }
352 :
353 :
354 : /**
355 : * Set a char inside this string at given index
356 : *
357 : * @param aChar is the char you want to write into this string
358 : * @param anIndex is the ofs where you want to write the given char
359 : * @return TRUE if successful
360 : */
361 :
362 : bool SetCharAt(char16_t aChar, uint32_t aIndex);
363 :
364 :
365 : /**
366 : * These methods are used to remove all occurrences of the
367 : * characters found in aSet from this string.
368 : *
369 : * @param aSet -- characters to be cut from this
370 : */
371 : #ifdef CharT_is_PRUnichar
372 : using nsTSubstring_CharT::StripChars;
373 : #endif
374 : void StripChars(const char* aSet);
375 : bool StripChars(const char* aSet, const fallible_t&);
376 :
377 :
378 : /**
379 : * This method strips whitespace throughout the string.
380 : */
381 : void StripWhitespace();
382 : bool StripWhitespace(const fallible_t&);
383 :
384 :
385 : /**
386 : * swaps occurence of 1 string for another
387 : */
388 :
389 : void ReplaceChar(char_type aOldChar, char_type aNewChar);
390 : void ReplaceChar(const char* aSet, char_type aNewChar);
391 : #ifdef CharT_is_PRUnichar
392 : void ReplaceChar(const char16_t* aSet, char16_t aNewChar);
393 : #endif
394 : /**
395 : * Replace all occurrences of aTarget with aNewValue.
396 : * The complexity of this function is O(n+m), n being the length of the string
397 : * and m being the length of aNewValue.
398 : */
399 : void ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue);
400 : void ReplaceSubstring(const char_type* aTarget, const char_type* aNewValue);
401 : MOZ_MUST_USE bool ReplaceSubstring(const self_type& aTarget,
402 : const self_type& aNewValue,
403 : const fallible_t&);
404 : MOZ_MUST_USE bool ReplaceSubstring(const char_type* aTarget,
405 : const char_type* aNewValue,
406 : const fallible_t&);
407 :
408 :
409 : /**
410 : * This method trims characters found in aTrimSet from
411 : * either end of the underlying string.
412 : *
413 : * @param aSet -- contains chars to be trimmed from both ends
414 : * @param aEliminateLeading
415 : * @param aEliminateTrailing
416 : * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored
417 : * @return this
418 : */
419 : void Trim(const char* aSet, bool aEliminateLeading = true,
420 : bool aEliminateTrailing = true, bool aIgnoreQuotes = false);
421 :
422 : /**
423 : * This method strips whitespace from string.
424 : * You can control whether whitespace is yanked from start and end of
425 : * string as well.
426 : *
427 : * @param aEliminateLeading controls stripping of leading ws
428 : * @param aEliminateTrailing controls stripping of trailing ws
429 : */
430 : void CompressWhitespace(bool aEliminateLeading = true,
431 : bool aEliminateTrailing = true);
432 :
433 :
434 : /**
435 : * assign/append/insert with _LOSSY_ conversion
436 : */
437 :
438 : void AssignWithConversion(const nsTAString_IncompatibleCharT& aString);
439 : void AssignWithConversion(const incompatible_char_type* aData,
440 : int32_t aLength = -1);
441 :
442 : #endif // !MOZ_STRING_WITH_OBSOLETE_API
443 :
444 : /**
445 : * Allow this string to be bound to a character buffer
446 : * until the string is rebound or mutated; the caller
447 : * must ensure that the buffer outlives the string.
448 : */
449 : void Rebind(const char_type* aData, size_type aLength);
450 :
451 : /**
452 : * verify restrictions for dependent strings
453 : */
454 78714 : void AssertValidDependentString()
455 : {
456 78714 : NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer");
457 78714 : NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length");
458 78714 : NS_ASSERTION(mData[mLength] == 0,
459 : "nsTDependentString must wrap only null-terminated strings. "
460 : "You are probably looking for nsTDependentSubstring.");
461 78714 : }
462 :
463 :
464 : protected:
465 :
466 : // allow subclasses to initialize fields directly
467 340425 : nsTString_CharT(char_type* aData, size_type aLength, DataFlags aDataFlags,
468 : ClassFlags aClassFlags)
469 340425 : : substring_type(aData, aLength, aDataFlags, aClassFlags)
470 : {
471 340425 : }
472 :
473 : struct Segment {
474 : uint32_t mBegin, mLength;
475 2469 : Segment(uint32_t aBegin, uint32_t aLength)
476 2469 : : mBegin(aBegin)
477 2469 : , mLength(aLength)
478 2469 : {}
479 : };
480 : };
481 :
482 :
483 258863 : class nsTFixedString_CharT : public nsTString_CharT
484 : {
485 : public:
486 :
487 : typedef nsTFixedString_CharT self_type;
488 : typedef nsTFixedString_CharT fixed_string_type;
489 :
490 : public:
491 :
492 : /**
493 : * @param aData
494 : * fixed-size buffer to be used by the string (the contents of
495 : * this buffer may be modified by the string)
496 : * @param aStorageSize
497 : * the size of the fixed buffer
498 : * @param aLength (optional)
499 : * the length of the string already contained in the buffer
500 : */
501 :
502 : nsTFixedString_CharT(char_type* aData, size_type aStorageSize)
503 : : string_type(aData, uint32_t(char_traits::length(aData)),
504 : DataFlags::TERMINATED | DataFlags::FIXED,
505 : ClassFlags::FIXED)
506 : , mFixedCapacity(aStorageSize - 1)
507 : , mFixedBuf(aData)
508 : {
509 : }
510 :
511 259251 : nsTFixedString_CharT(char_type* aData, size_type aStorageSize,
512 : size_type aLength)
513 518504 : : string_type(aData, aLength, DataFlags::TERMINATED | DataFlags::FIXED,
514 : ClassFlags::FIXED)
515 259253 : , mFixedCapacity(aStorageSize - 1)
516 518504 : , mFixedBuf(aData)
517 : {
518 : // null-terminate
519 259253 : mFixedBuf[aLength] = char_type(0);
520 259253 : }
521 :
522 : // |operator=| does not inherit, so we must define our own
523 : self_type& operator=(char_type aChar)
524 : {
525 : Assign(aChar);
526 : return *this;
527 : }
528 1 : self_type& operator=(const char_type* aData)
529 : {
530 1 : Assign(aData);
531 1 : return *this;
532 : }
533 : self_type& operator=(const substring_type& aStr)
534 : {
535 : Assign(aStr);
536 : return *this;
537 : }
538 : self_type& operator=(const substring_tuple_type& aTuple)
539 : {
540 : Assign(aTuple);
541 : return *this;
542 : }
543 :
544 : protected:
545 :
546 : friend class nsTSubstring_CharT;
547 :
548 : size_type mFixedCapacity;
549 : char_type* mFixedBuf;
550 : };
551 :
552 :
553 : /**
554 : * nsTAutoString_CharT
555 : *
556 : * Subclass of nsTString_CharT that adds support for stack-based string
557 : * allocation. It is normally not a good idea to use this class on the
558 : * heap, because it will allocate space which may be wasted if the string
559 : * it contains is significantly smaller or any larger than 64 characters.
560 : *
561 : * NAMES:
562 : * nsAutoString for wide characters
563 : * nsAutoCString for narrow characters
564 : */
565 258301 : class MOZ_NON_MEMMOVABLE nsTAutoString_CharT : public nsTFixedString_CharT
566 : {
567 : public:
568 :
569 : typedef nsTAutoString_CharT self_type;
570 :
571 : public:
572 :
573 : /**
574 : * constructors
575 : */
576 :
577 226296 : nsTAutoString_CharT()
578 226296 : : fixed_string_type(mStorage, kDefaultStorageSize, 0)
579 : {
580 226298 : }
581 :
582 : explicit
583 0 : nsTAutoString_CharT(char_type aChar)
584 0 : : fixed_string_type(mStorage, kDefaultStorageSize, 0)
585 : {
586 0 : Assign(aChar);
587 0 : }
588 :
589 : explicit
590 23589 : nsTAutoString_CharT(const char_type* aData, size_type aLength = size_type(-1))
591 23589 : : fixed_string_type(mStorage, kDefaultStorageSize, 0)
592 : {
593 23589 : Assign(aData, aLength);
594 23589 : }
595 :
596 : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
597 : explicit
598 : nsTAutoString_CharT(char16ptr_t aData, size_type aLength = size_type(-1))
599 : : nsTAutoString_CharT(static_cast<const char16_t*>(aData), aLength)
600 : {
601 : }
602 : #endif
603 :
604 2352 : nsTAutoString_CharT(const self_type& aStr)
605 2352 : : fixed_string_type(mStorage, kDefaultStorageSize, 0)
606 : {
607 2352 : Assign(aStr);
608 2352 : }
609 :
610 : explicit
611 6374 : nsTAutoString_CharT(const substring_type& aStr)
612 6374 : : fixed_string_type(mStorage, kDefaultStorageSize, 0)
613 : {
614 6374 : Assign(aStr);
615 6374 : }
616 :
617 0 : MOZ_IMPLICIT nsTAutoString_CharT(const substring_tuple_type& aTuple)
618 0 : : fixed_string_type(mStorage, kDefaultStorageSize, 0)
619 : {
620 0 : Assign(aTuple);
621 0 : }
622 :
623 : // |operator=| does not inherit, so we must define our own
624 0 : self_type& operator=(char_type aChar)
625 : {
626 0 : Assign(aChar);
627 0 : return *this;
628 : }
629 18 : self_type& operator=(const char_type* aData)
630 : {
631 18 : Assign(aData);
632 18 : return *this;
633 : }
634 : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
635 : self_type& operator=(char16ptr_t aStr)
636 : {
637 : Assign(aStr);
638 : return *this;
639 : }
640 : #endif
641 20431 : self_type& operator=(const self_type& aStr)
642 : {
643 20431 : Assign(aStr);
644 20431 : return *this;
645 : }
646 1161 : self_type& operator=(const substring_type& aStr)
647 : {
648 1161 : Assign(aStr);
649 1161 : return *this;
650 : }
651 10 : self_type& operator=(const substring_tuple_type& aTuple)
652 : {
653 10 : Assign(aTuple);
654 10 : return *this;
655 : }
656 :
657 : enum
658 : {
659 : kDefaultStorageSize = 64
660 : };
661 :
662 : private:
663 :
664 : char_type mStorage[kDefaultStorageSize];
665 : };
666 :
667 :
668 : //
669 : // nsAutoString stores pointers into itself which are invalidated when an
670 : // nsTArray is resized, so nsTArray must not be instantiated with nsAutoString
671 : // elements!
672 : //
673 : template<class E> class nsTArrayElementTraits;
674 : template<>
675 : class nsTArrayElementTraits<nsTAutoString_CharT>
676 : {
677 : public:
678 : template<class A> struct Dont_Instantiate_nsTArray_of;
679 : template<class A> struct Instead_Use_nsTArray_of;
680 :
681 : static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
682 : Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE)
683 : {
684 : return 0;
685 : }
686 : template<class A>
687 : static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
688 : Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE, const A& aArg)
689 : {
690 : return 0;
691 : }
692 : static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
693 : Destruct(Instead_Use_nsTArray_of<nsTString_CharT>* aE)
694 : {
695 : return 0;
696 : }
697 : };
698 :
699 : /**
700 : * nsTXPIDLString extends nsTString such that:
701 : *
702 : * (1) mData can be null
703 : * (2) objects of this type can be automatically cast to |const CharT*|
704 : * (3) getter_Copies method is supported to adopt data allocated with
705 : * moz_xmalloc, such as "out string" parameters in XPIDL.
706 : *
707 : * NAMES:
708 : * nsXPIDLString for wide characters
709 : * nsXPIDLCString for narrow characters
710 : */
711 4842 : class nsTXPIDLString_CharT : public nsTString_CharT
712 : {
713 : public:
714 :
715 : typedef nsTXPIDLString_CharT self_type;
716 :
717 : public:
718 :
719 4897 : nsTXPIDLString_CharT()
720 4897 : : string_type(char_traits::sEmptyBuffer, 0,
721 4897 : DataFlags::TERMINATED | DataFlags::VOIDED, ClassFlags(0))
722 : {
723 4897 : }
724 :
725 : // copy-constructor required to avoid default
726 : nsTXPIDLString_CharT(const self_type& aStr)
727 : : string_type(char_traits::sEmptyBuffer, 0,
728 : DataFlags::TERMINATED | DataFlags::VOIDED, ClassFlags(0))
729 : {
730 : Assign(aStr);
731 : }
732 :
733 : // return nullptr if we are voided
734 : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
735 : char16ptr_t get() const
736 : #else
737 4055 : const char_type* get() const
738 : #endif
739 : {
740 4055 : return (mDataFlags & DataFlags::VOIDED) ? nullptr : mData;
741 : }
742 :
743 : // this case operator is the reason why this class cannot just be a
744 : // typedef for nsTString
745 3991 : operator const char_type*() const
746 : {
747 3991 : return get();
748 : }
749 :
750 : // need this to diambiguous operator[int]
751 : char_type operator[](int32_t aIndex) const
752 : {
753 : return CharAt(index_type(aIndex));
754 : }
755 :
756 : // |operator=| does not inherit, so we must define our own
757 : self_type& operator=(char_type aChar)
758 : {
759 : Assign(aChar);
760 : return *this;
761 : }
762 0 : self_type& operator=(const char_type* aStr)
763 : {
764 0 : Assign(aStr);
765 0 : return *this;
766 : }
767 0 : self_type& operator=(const self_type& aStr)
768 : {
769 0 : Assign(aStr);
770 0 : return *this;
771 : }
772 9 : self_type& operator=(const substring_type& aStr)
773 : {
774 9 : Assign(aStr);
775 9 : return *this;
776 : }
777 : self_type& operator=(const substring_tuple_type& aTuple)
778 : {
779 : Assign(aTuple);
780 : return *this;
781 : }
782 : };
783 :
784 :
785 : /**
786 : * getter_Copies support for use with raw string out params:
787 : *
788 : * NS_IMETHOD GetBlah(char**);
789 : *
790 : * void some_function()
791 : * {
792 : * nsXPIDLCString blah;
793 : * GetBlah(getter_Copies(blah));
794 : * // ...
795 : * }
796 : */
797 : class MOZ_STACK_CLASS nsTGetterCopies_CharT
798 : {
799 : public:
800 : typedef CharT char_type;
801 :
802 5215 : explicit nsTGetterCopies_CharT(nsTSubstring_CharT& aStr)
803 5215 : : mString(aStr)
804 5215 : , mData(nullptr)
805 : {
806 5215 : }
807 :
808 5215 : ~nsTGetterCopies_CharT()
809 5215 : {
810 5215 : mString.Adopt(mData); // OK if mData is null
811 5215 : }
812 :
813 5215 : operator char_type**()
814 : {
815 5215 : return &mData;
816 : }
817 :
818 : private:
819 : nsTSubstring_CharT& mString;
820 : char_type* mData;
821 : };
822 :
823 : inline nsTGetterCopies_CharT
824 5215 : getter_Copies(nsTSubstring_CharT& aString)
825 : {
826 5215 : return nsTGetterCopies_CharT(aString);
827 : }
828 :
829 :
830 : /**
831 : * nsTAdoptingString extends nsTXPIDLString such that:
832 : *
833 : * (1) Adopt given string on construction or assignment, i.e. take
834 : * the value of what's given, and make what's given forget its
835 : * value. Note that this class violates constness in a few
836 : * places. Be careful!
837 : */
838 435 : class nsTAdoptingString_CharT : public nsTXPIDLString_CharT
839 : {
840 : public:
841 :
842 : typedef nsTAdoptingString_CharT self_type;
843 :
844 : public:
845 :
846 471 : explicit nsTAdoptingString_CharT()
847 471 : {
848 471 : }
849 0 : explicit nsTAdoptingString_CharT(char_type* aStr,
850 : size_type aLength = size_type(-1))
851 0 : {
852 0 : Adopt(aStr, aLength);
853 0 : }
854 :
855 : // copy-constructor required to adopt on copy. Note that this
856 : // will violate the constness of |aStr| in the operator=()
857 : // call. |aStr| will be truncated as a side-effect of this
858 : // constructor.
859 0 : nsTAdoptingString_CharT(const self_type& aStr)
860 0 : : nsTXPIDLString_CharT()
861 : {
862 0 : *this = aStr;
863 0 : }
864 :
865 : // |operator=| does not inherit, so we must define our own
866 : self_type& operator=(const substring_type& aStr)
867 : {
868 : Assign(aStr);
869 : return *this;
870 : }
871 : self_type& operator=(const substring_tuple_type& aTuple)
872 : {
873 : Assign(aTuple);
874 : return *this;
875 : }
876 :
877 : // Adopt(), if possible, when assigning to a self_type&. Note
878 : // that this violates the constness of aStr, aStr is always
879 : // truncated when this operator is called.
880 : self_type& operator=(const self_type& aStr);
881 :
882 : private:
883 : self_type& operator=(const char_type* aData) = delete;
884 : self_type& operator=(char_type* aData) = delete;
885 : };
886 :
|