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"
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.
14 * nsString for wide characters
15 * nsCString for narrow characters
17 * This class is also known as nsAFlat[C]String, where "flat" is used
18 * to denote a null-terminated string.
20 class nsTString_CharT
: public nsTSubstring_CharT
24 typedef nsTString_CharT self_type
;
38 nsTString_CharT(const char_type
* aData
, size_type aLength
= size_type(-1))
41 Assign(aData
, aLength
);
44 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
46 nsTString_CharT(char16ptr_t aStr
, size_type aLength
= size_type(-1))
49 Assign(static_cast<const char16_t
*>(aStr
), aLength
);
53 nsTString_CharT(const self_type
& aStr
)
59 MOZ_IMPLICIT
nsTString_CharT(const substring_tuple_type
& aTuple
)
66 nsTString_CharT(const substring_type
& aReadable
)
73 // |operator=| does not inherit, so we must define our own
74 self_type
& operator=(char_type aChar
)
79 self_type
& operator=(const char_type
* aData
)
84 self_type
& operator=(const self_type
& aStr
)
89 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
90 self_type
& operator=(const char16ptr_t aStr
)
92 Assign(static_cast<const char16_t
*>(aStr
));
96 self_type
& operator=(const substring_type
& aStr
)
101 self_type
& operator=(const substring_tuple_type
& aTuple
)
108 * returns the null-terminated string
111 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
112 char16ptr_t
get() const
114 const char_type
* get() const
122 * returns character at specified index.
124 * NOTE: unlike nsTSubstring::CharAt, this function allows you to index
125 * the null terminator character.
128 char_type
CharAt(index_type aIndex
) const
130 NS_ASSERTION(aIndex
<= mLength
, "index exceeds allowable range");
131 return mData
[aIndex
];
134 char_type
operator[](index_type aIndex
) const
136 return CharAt(aIndex
);
140 #if MOZ_STRING_WITH_OBSOLETE_API
144 * Search for the given substring within this string.
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
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;
159 #ifdef CharT_is_PRUnichar
160 int32_t Find(const nsAFlatString
& 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
168 return Find(static_cast<const char16_t
*>(aString
), aOffset
, aCount
);
175 * This methods scans the string backwards, looking for the given string
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
183 * @return offset in string, or kNotFound
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;
191 #ifdef CharT_is_PRUnichar
192 int32_t RFind(const nsAFlatString
& 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;
200 * Search for given char within this string
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
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;
215 * This method searches this string for the first character found in
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
224 int32_t FindCharInSet(const char* aString
, int32_t aOffset
= 0) const;
225 int32_t FindCharInSet(const self_type
& aString
, int32_t aOffset
= 0) const
227 return FindCharInSet(aString
.get(), aOffset
);
230 #ifdef CharT_is_PRUnichar
231 int32_t FindCharInSet(const char16_t
* aString
, int32_t aOffset
= 0) const;
236 * This method searches this string for the last character found in
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
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
248 return RFindCharInSet(aString
.get(), aOffset
);
253 * Compares a given string to this string.
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
262 int32_t Compare(const char* aString
, bool aIgnoreCase
= false,
263 int32_t aCount
= -1) const;
268 * Equality check between given string and this string.
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
276 bool EqualsIgnoreCase(const char* aString
, int32_t aCount
= -1) const
278 return Compare(aString
, true, aCount
) == 0;
281 bool EqualsIgnoreCase(const char* aString
, int32_t aCount
= -1) const;
284 #endif // !CharT_is_PRUnichar
287 * Perform string to double-precision float conversion.
289 * @param aErrorCode will contain error if one occurs
290 * @return double-precision float rep of string value
292 double ToDouble(nsresult
* aErrorCode
) const;
295 * Perform string to single-precision float conversion.
297 * @param aErrorCode will contain error if one occurs
298 * @return single-precision float rep of string value
300 float ToFloat(nsresult
* aErrorCode
) const
302 return (float)ToDouble(aErrorCode
);
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
312 int32_t ToInteger(nsresult
* aErrorCode
, uint32_t aRadix
= kRadix10
) const;
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
320 int64_t ToInteger64(nsresult
* aErrorCode
, uint32_t aRadix
= kRadix10
) const;
324 * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
325 * any _other_ way than they are now. Consider these alternatives
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
331 * as opposed to the current signature
333 * aReadable.Left(aWritable, 17); // ...a member function that does the assignment
335 * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
337 * aWritable = Substring(aReadable, 0, 17);
340 size_type
Mid(self_type
& aResult
, uint32_t aStartPos
, uint32_t aCount
) const;
342 size_type
Left(self_type
& aResult
, size_type aCount
) const
344 return Mid(aResult
, 0, aCount
);
347 size_type
Right(self_type
& aResult
, size_type aCount
) const
349 aCount
= XPCOM_MIN(mLength
, aCount
);
350 return Mid(aResult
, mLength
- aCount
, aCount
);
355 * Set a char inside this string at given index
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
362 bool SetCharAt(char16_t aChar
, uint32_t aIndex
);
366 * These methods are used to remove all occurrences of the
367 * characters found in aSet from this string.
369 * @param aSet -- characters to be cut from this
371 void StripChars(const char* aSet
);
375 * This method strips whitespace throughout the string.
377 void StripWhitespace();
381 * swaps occurence of 1 string for another
384 void ReplaceChar(char_type aOldChar
, char_type aNewChar
);
385 void ReplaceChar(const char* aSet
, char_type aNewChar
);
386 #ifdef CharT_is_PRUnichar
387 void ReplaceChar(const char16_t
* aSet
, char16_t aNewChar
);
389 void ReplaceSubstring(const self_type
& aTarget
, const self_type
& aNewValue
);
390 void ReplaceSubstring(const char_type
* aTarget
, const char_type
* aNewValue
);
394 * This method trims characters found in aTrimSet from
395 * either end of the underlying string.
397 * @param aSet -- contains chars to be trimmed from both ends
398 * @param aEliminateLeading
399 * @param aEliminateTrailing
400 * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored
403 void Trim(const char* aSet
, bool aEliminateLeading
= true,
404 bool aEliminateTrailing
= true, bool aIgnoreQuotes
= false);
407 * This method strips whitespace from string.
408 * You can control whether whitespace is yanked from start and end of
411 * @param aEliminateLeading controls stripping of leading ws
412 * @param aEliminateTrailing controls stripping of trailing ws
414 void CompressWhitespace(bool aEliminateLeading
= true,
415 bool aEliminateTrailing
= true);
419 * assign/append/insert with _LOSSY_ conversion
422 void AssignWithConversion(const nsTAString_IncompatibleCharT
& aString
);
423 void AssignWithConversion(const incompatible_char_type
* aData
,
424 int32_t aLength
= -1);
426 #endif // !MOZ_STRING_WITH_OBSOLETE_API
429 * Allow this string to be bound to a character buffer
430 * until the string is rebound or mutated; the caller
431 * must ensure that the buffer outlives the string.
433 void Rebind(const char_type
* aData
, size_type aLength
);
436 * verify restrictions for dependent strings
438 void AssertValidDepedentString()
440 NS_ASSERTION(mData
, "nsTDependentString must wrap a non-NULL buffer");
441 NS_ASSERTION(mLength
!= size_type(-1), "nsTDependentString has bogus length");
442 NS_ASSERTION(mData
[mLength
] == 0,
443 "nsTDependentString must wrap only null-terminated strings. "
444 "You are probably looking for nsTDependentSubstring.");
451 nsTString_CharT(uint32_t aFlags
)
452 : substring_type(aFlags
)
456 // allow subclasses to initialize fields directly
457 nsTString_CharT(char_type
* aData
, size_type aLength
, uint32_t aFlags
)
458 : substring_type(aData
, aLength
, aFlags
)
464 class nsTFixedString_CharT
: public nsTString_CharT
468 typedef nsTFixedString_CharT self_type
;
469 typedef nsTFixedString_CharT fixed_string_type
;
475 * fixed-size buffer to be used by the string (the contents of
476 * this buffer may be modified by the string)
477 * @param aStorageSize
478 * the size of the fixed buffer
479 * @param aLength (optional)
480 * the length of the string already contained in the buffer
483 nsTFixedString_CharT(char_type
* aData
, size_type aStorageSize
)
484 : string_type(aData
, uint32_t(char_traits::length(aData
)),
485 F_TERMINATED
| F_FIXED
| F_CLASS_FIXED
)
486 , mFixedCapacity(aStorageSize
- 1)
491 nsTFixedString_CharT(char_type
* aData
, size_type aStorageSize
,
493 : string_type(aData
, aLength
, F_TERMINATED
| F_FIXED
| F_CLASS_FIXED
)
494 , mFixedCapacity(aStorageSize
- 1)
498 mFixedBuf
[aLength
] = char_type(0);
501 // |operator=| does not inherit, so we must define our own
502 self_type
& operator=(char_type aChar
)
507 self_type
& operator=(const char_type
* aData
)
512 self_type
& operator=(const substring_type
& aStr
)
517 self_type
& operator=(const substring_tuple_type
& aTuple
)
525 friend class nsTSubstring_CharT
;
527 size_type mFixedCapacity
;
528 char_type
* mFixedBuf
;
533 * nsTAutoString_CharT
535 * Subclass of nsTString_CharT that adds support for stack-based string
536 * allocation. It is normally not a good idea to use this class on the
537 * heap, because it will allocate space which may be wasted if the string
538 * it contains is significantly smaller or any larger than 64 characters.
541 * nsAutoString for wide characters
542 * nsAutoCString for narrow characters
544 class nsTAutoString_CharT
: public nsTFixedString_CharT
548 typedef nsTAutoString_CharT self_type
;
556 nsTAutoString_CharT()
557 : fixed_string_type(mStorage
, kDefaultStorageSize
, 0)
562 nsTAutoString_CharT(char_type aChar
)
563 : fixed_string_type(mStorage
, kDefaultStorageSize
, 0)
569 nsTAutoString_CharT(const char_type
* aData
, size_type aLength
= size_type(-1))
570 : fixed_string_type(mStorage
, kDefaultStorageSize
, 0)
572 Assign(aData
, aLength
);
575 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
577 nsTAutoString_CharT(char16ptr_t aData
, size_type aLength
= size_type(-1))
578 : nsTAutoString_CharT(static_cast<const char16_t
*>(aData
), aLength
)
583 nsTAutoString_CharT(const self_type
& aStr
)
584 : fixed_string_type(mStorage
, kDefaultStorageSize
, 0)
590 nsTAutoString_CharT(const substring_type
& aStr
)
591 : fixed_string_type(mStorage
, kDefaultStorageSize
, 0)
596 MOZ_IMPLICIT
nsTAutoString_CharT(const substring_tuple_type
& aTuple
)
597 : fixed_string_type(mStorage
, kDefaultStorageSize
, 0)
602 // |operator=| does not inherit, so we must define our own
603 self_type
& operator=(char_type aChar
)
608 self_type
& operator=(const char_type
* aData
)
613 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
614 self_type
& operator=(char16ptr_t aStr
)
620 self_type
& operator=(const self_type
& aStr
)
625 self_type
& operator=(const substring_type
& aStr
)
630 self_type
& operator=(const substring_tuple_type
& aTuple
)
638 kDefaultStorageSize
= 64
643 char_type mStorage
[kDefaultStorageSize
];
648 // nsAutoString stores pointers into itself which are invalidated when an
649 // nsTArray is resized, so nsTArray must not be instantiated with nsAutoString
652 template<class E
> class nsTArrayElementTraits
;
654 class nsTArrayElementTraits
<nsTAutoString_CharT
>
657 template<class A
> struct Dont_Instantiate_nsTArray_of
;
658 template<class A
> struct Instead_Use_nsTArray_of
;
660 static Dont_Instantiate_nsTArray_of
<nsTAutoString_CharT
>*
661 Construct(Instead_Use_nsTArray_of
<nsTString_CharT
>* aE
)
666 static Dont_Instantiate_nsTArray_of
<nsTAutoString_CharT
>*
667 Construct(Instead_Use_nsTArray_of
<nsTString_CharT
>* aE
, const A
& aArg
)
671 static Dont_Instantiate_nsTArray_of
<nsTAutoString_CharT
>*
672 Destruct(Instead_Use_nsTArray_of
<nsTString_CharT
>* aE
)
679 * nsTXPIDLString extends nsTString such that:
681 * (1) mData can be null
682 * (2) objects of this type can be automatically cast to |const CharT*|
683 * (3) getter_Copies method is supported to adopt data allocated with
684 * NS_Alloc, such as "out string" parameters in XPIDL.
687 * nsXPIDLString for wide characters
688 * nsXPIDLCString for narrow characters
690 class nsTXPIDLString_CharT
: public nsTString_CharT
694 typedef nsTXPIDLString_CharT self_type
;
698 nsTXPIDLString_CharT()
699 : string_type(char_traits::sEmptyBuffer
, 0, F_TERMINATED
| F_VOIDED
)
703 // copy-constructor required to avoid default
704 nsTXPIDLString_CharT(const self_type
& aStr
)
705 : string_type(char_traits::sEmptyBuffer
, 0, F_TERMINATED
| F_VOIDED
)
710 // return nullptr if we are voided
711 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
712 char16ptr_t
get() const
714 const char_type
* get() const
717 return (mFlags
& F_VOIDED
) ? nullptr : mData
;
720 // this case operator is the reason why this class cannot just be a
721 // typedef for nsTString
722 operator const char_type
*() const
727 // need this to diambiguous operator[int]
728 char_type
operator[](int32_t aIndex
) const
730 return CharAt(index_type(aIndex
));
733 // |operator=| does not inherit, so we must define our own
734 self_type
& operator=(char_type aChar
)
739 self_type
& operator=(const char_type
* aStr
)
744 self_type
& operator=(const self_type
& aStr
)
749 self_type
& operator=(const substring_type
& aStr
)
754 self_type
& operator=(const substring_tuple_type
& aTuple
)
763 * getter_Copies support for use with raw string out params:
765 * NS_IMETHOD GetBlah(char**);
767 * void some_function()
769 * nsXPIDLCString blah;
770 * GetBlah(getter_Copies(blah));
774 class MOZ_STACK_CLASS nsTGetterCopies_CharT
777 typedef CharT char_type
;
779 explicit nsTGetterCopies_CharT(nsTSubstring_CharT
& aStr
)
785 ~nsTGetterCopies_CharT()
787 mString
.Adopt(mData
); // OK if mData is null
790 operator char_type
**()
796 nsTSubstring_CharT
& mString
;
800 inline nsTGetterCopies_CharT
801 getter_Copies(nsTSubstring_CharT
& aString
)
803 return nsTGetterCopies_CharT(aString
);
808 * nsTAdoptingString extends nsTXPIDLString such that:
810 * (1) Adopt given string on construction or assignment, i.e. take
811 * the value of what's given, and make what's given forget its
812 * value. Note that this class violates constness in a few
813 * places. Be careful!
815 class nsTAdoptingString_CharT
: public nsTXPIDLString_CharT
819 typedef nsTAdoptingString_CharT self_type
;
823 explicit nsTAdoptingString_CharT()
826 explicit nsTAdoptingString_CharT(char_type
* aStr
,
827 size_type aLength
= size_type(-1))
829 Adopt(aStr
, aLength
);
832 // copy-constructor required to adopt on copy. Note that this
833 // will violate the constness of |aStr| in the operator=()
834 // call. |aStr| will be truncated as a side-effect of this
836 nsTAdoptingString_CharT(const self_type
& aStr
)
841 // |operator=| does not inherit, so we must define our own
842 self_type
& operator=(const substring_type
& aStr
)
847 self_type
& operator=(const substring_tuple_type
& aTuple
)
853 // Adopt(), if possible, when assigning to a self_type&. Note
854 // that this violates the constness of aStr, aStr is always
855 // truncated when this operator is called.
856 self_type
& operator=(const self_type
& aStr
);
859 self_type
& operator=(const char_type
* aData
) MOZ_DELETE
;
860 self_type
& operator=(char_type
* aData
) MOZ_DELETE
;