diff options
Diffstat (limited to 'xpcom/string/nsTString.h')
-rw-r--r-- | xpcom/string/nsTString.h | 883 |
1 files changed, 883 insertions, 0 deletions
diff --git a/xpcom/string/nsTString.h b/xpcom/string/nsTString.h new file mode 100644 index 000000000..6fbb9d3ad --- /dev/null +++ b/xpcom/string/nsTString.h @@ -0,0 +1,883 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +// IWYU pragma: private, include "nsString.h" + +/** + * This is the canonical null-terminated string class. All subclasses + * promise null-terminated storage. Instances of this class allocate + * strings on the heap. + * + * NAMES: + * nsString for wide characters + * nsCString for narrow characters + * + * This class is also known as nsAFlat[C]String, where "flat" is used + * to denote a null-terminated string. + */ +class nsTString_CharT : public nsTSubstring_CharT +{ +public: + + typedef nsTString_CharT self_type; + +public: + + /** + * constructors + */ + + nsTString_CharT() + : substring_type() + { + } + + explicit + nsTString_CharT(const char_type* aData, size_type aLength = size_type(-1)) + : substring_type() + { + Assign(aData, aLength); + } + +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) + explicit + nsTString_CharT(char16ptr_t aStr, size_type aLength = size_type(-1)) + : substring_type() + { + Assign(static_cast<const char16_t*>(aStr), aLength); + } +#endif + + nsTString_CharT(const self_type& aStr) + : substring_type() + { + Assign(aStr); + } + + MOZ_IMPLICIT nsTString_CharT(const substring_tuple_type& aTuple) + : substring_type() + { + Assign(aTuple); + } + + explicit + nsTString_CharT(const substring_type& aReadable) + : substring_type() + { + Assign(aReadable); + } + + + // |operator=| does not inherit, so we must define our own + self_type& operator=(char_type aChar) + { + Assign(aChar); + return *this; + } + self_type& operator=(const char_type* aData) + { + Assign(aData); + return *this; + } + self_type& operator=(const self_type& aStr) + { + Assign(aStr); + return *this; + } +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) + self_type& operator=(const char16ptr_t aStr) + { + Assign(static_cast<const char16_t*>(aStr)); + return *this; + } +#endif + self_type& operator=(const substring_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_tuple_type& aTuple) + { + Assign(aTuple); + return *this; + } + + /** + * returns the null-terminated string + */ + +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) + char16ptr_t get() const +#else + const char_type* get() const +#endif + { + return mData; + } + + + /** + * returns character at specified index. + * + * NOTE: unlike nsTSubstring::CharAt, this function allows you to index + * the null terminator character. + */ + + char_type CharAt(index_type aIndex) const + { + NS_ASSERTION(aIndex <= mLength, "index exceeds allowable range"); + return mData[aIndex]; + } + + char_type operator[](index_type aIndex) const + { + return CharAt(aIndex); + } + + +#if MOZ_STRING_WITH_OBSOLETE_API + + + /** + * Search for the given substring within this string. + * + * @param aString is substring to be sought in this + * @param aIgnoreCase selects case sensitivity + * @param aOffset tells us where in this string to start searching + * @param aCount tells us how far from the offset we are to search. Use + * -1 to search the whole string. + * @return offset in string, or kNotFound + */ + + int32_t Find(const nsCString& aString, bool aIgnoreCase = false, + int32_t aOffset = 0, int32_t aCount = -1) const; + int32_t Find(const char* aString, bool aIgnoreCase = false, + int32_t aOffset = 0, int32_t aCount = -1) const; + +#ifdef CharT_is_PRUnichar + int32_t Find(const nsAFlatString& aString, int32_t aOffset = 0, + int32_t aCount = -1) const; + int32_t Find(const char16_t* aString, int32_t aOffset = 0, + int32_t aCount = -1) const; +#ifdef MOZ_USE_CHAR16_WRAPPER + int32_t Find(char16ptr_t aString, int32_t aOffset = 0, + int32_t aCount = -1) const + { + return Find(static_cast<const char16_t*>(aString), aOffset, aCount); + } +#endif +#endif + + + /** + * This methods scans the string backwards, looking for the given string + * + * @param aString is substring to be sought in this + * @param aIgnoreCase tells us whether or not to do caseless compare + * @param aOffset tells us where in this string to start searching. + * Use -1 to search from the end of the string. + * @param aCount tells us how many iterations to make starting at the + * given offset. + * @return offset in string, or kNotFound + */ + + int32_t RFind(const nsCString& aString, bool aIgnoreCase = false, + int32_t aOffset = -1, int32_t aCount = -1) const; + int32_t RFind(const char* aCString, bool aIgnoreCase = false, + int32_t aOffset = -1, int32_t aCount = -1) const; + +#ifdef CharT_is_PRUnichar + int32_t RFind(const nsAFlatString& aString, int32_t aOffset = -1, + int32_t aCount = -1) const; + int32_t RFind(const char16_t* aString, int32_t aOffset = -1, + int32_t aCount = -1) const; +#endif + + + /** + * Search for given char within this string + * + * @param aChar is the character to search for + * @param aOffset tells us where in this string to start searching + * @param aCount tells us how far from the offset we are to search. + * Use -1 to search the whole string. + * @return offset in string, or kNotFound + */ + + // int32_t FindChar( char16_t aChar, int32_t aOffset=0, int32_t aCount=-1 ) const; + int32_t RFindChar(char16_t aChar, int32_t aOffset = -1, + int32_t aCount = -1) const; + + + /** + * This method searches this string for the first character found in + * the given string. + * + * @param aString contains set of chars to be found + * @param aOffset tells us where in this string to start searching + * (counting from left) + * @return offset in string, or kNotFound + */ + + int32_t FindCharInSet(const char* aString, int32_t aOffset = 0) const; + int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const + { + return FindCharInSet(aString.get(), aOffset); + } + +#ifdef CharT_is_PRUnichar + int32_t FindCharInSet(const char16_t* aString, int32_t aOffset = 0) const; +#endif + + + /** + * This method searches this string for the last character found in + * the given string. + * + * @param aString contains set of chars to be found + * @param aOffset tells us where in this string to start searching + * (counting from left) + * @return offset in string, or kNotFound + */ + + int32_t RFindCharInSet(const char_type* aString, int32_t aOffset = -1) const; + int32_t RFindCharInSet(const self_type& aString, int32_t aOffset = -1) const + { + return RFindCharInSet(aString.get(), aOffset); + } + + + /** + * Compares a given string to this string. + * + * @param aString is the string to be compared + * @param aIgnoreCase tells us how to treat case + * @param aCount tells us how many chars to compare + * @return -1,0,1 + */ + +#ifdef CharT_is_char + int32_t Compare(const char* aString, bool aIgnoreCase = false, + int32_t aCount = -1) const; +#endif + + + /** + * Equality check between given string and this string. + * + * @param aString is the string to check + * @param aIgnoreCase tells us how to treat case + * @param aCount tells us how many chars to compare + * @return boolean + */ +#ifdef CharT_is_char + bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const + { + return Compare(aString, true, aCount) == 0; + } +#else + bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const; + + +#endif // !CharT_is_PRUnichar + + /** + * Perform string to double-precision float conversion. + * + * @param aErrorCode will contain error if one occurs + * @return double-precision float rep of string value + */ + double ToDouble(nsresult* aErrorCode) const; + + /** + * Perform string to single-precision float conversion. + * + * @param aErrorCode will contain error if one occurs + * @return single-precision float rep of string value + */ + float ToFloat(nsresult* aErrorCode) const + { + return (float)ToDouble(aErrorCode); + } + + + /** + * Perform string to int conversion. + * @param aErrorCode will contain error if one occurs + * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. + * @return int rep of string value, and possible (out) error code + */ + int32_t ToInteger(nsresult* aErrorCode, uint32_t aRadix = kRadix10) const; + + /** + * Perform string to 64-bit int conversion. + * @param aErrorCode will contain error if one occurs + * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. + * @return 64-bit int rep of string value, and possible (out) error code + */ + int64_t ToInteger64(nsresult* aErrorCode, uint32_t aRadix = kRadix10) const; + + + /** + * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost + * any _other_ way than they are now. Consider these alternatives + * + * aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| + * aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| + * Left(aReadable, 17, aWritable); // ...a global function that does the assignment + * + * as opposed to the current signature + * + * aReadable.Left(aWritable, 17); // ...a member function that does the assignment + * + * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality + * + * aWritable = Substring(aReadable, 0, 17); + */ + + size_type Mid(self_type& aResult, uint32_t aStartPos, uint32_t aCount) const; + + size_type Left(self_type& aResult, size_type aCount) const + { + return Mid(aResult, 0, aCount); + } + + size_type Right(self_type& aResult, size_type aCount) const + { + aCount = XPCOM_MIN(mLength, aCount); + return Mid(aResult, mLength - aCount, aCount); + } + + + /** + * Set a char inside this string at given index + * + * @param aChar is the char you want to write into this string + * @param anIndex is the ofs where you want to write the given char + * @return TRUE if successful + */ + + bool SetCharAt(char16_t aChar, uint32_t aIndex); + + + /** + * These methods are used to remove all occurrences of the + * characters found in aSet from this string. + * + * @param aSet -- characters to be cut from this + */ + void StripChars(const char* aSet); + bool StripChars(const char* aSet, const fallible_t&); + + + /** + * This method strips whitespace throughout the string. + */ + void StripWhitespace(); + bool StripWhitespace(const fallible_t&); + + + /** + * swaps occurence of 1 string for another + */ + + void ReplaceChar(char_type aOldChar, char_type aNewChar); + void ReplaceChar(const char* aSet, char_type aNewChar); +#ifdef CharT_is_PRUnichar + void ReplaceChar(const char16_t* aSet, char16_t aNewChar); +#endif + /** + * Replace all occurrences of aTarget with aNewValue. + * The complexity of this function is O(n+m), n being the length of the string + * and m being the length of aNewValue. + */ + void ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue); + void ReplaceSubstring(const char_type* aTarget, const char_type* aNewValue); + MOZ_MUST_USE bool ReplaceSubstring(const self_type& aTarget, + const self_type& aNewValue, + const fallible_t&); + MOZ_MUST_USE bool ReplaceSubstring(const char_type* aTarget, + const char_type* aNewValue, + const fallible_t&); + + + /** + * This method trims characters found in aTrimSet from + * either end of the underlying string. + * + * @param aSet -- contains chars to be trimmed from both ends + * @param aEliminateLeading + * @param aEliminateTrailing + * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored + * @return this + */ + void Trim(const char* aSet, bool aEliminateLeading = true, + bool aEliminateTrailing = true, bool aIgnoreQuotes = false); + + /** + * This method strips whitespace from string. + * You can control whether whitespace is yanked from start and end of + * string as well. + * + * @param aEliminateLeading controls stripping of leading ws + * @param aEliminateTrailing controls stripping of trailing ws + */ + void CompressWhitespace(bool aEliminateLeading = true, + bool aEliminateTrailing = true); + + + /** + * assign/append/insert with _LOSSY_ conversion + */ + + void AssignWithConversion(const nsTAString_IncompatibleCharT& aString); + void AssignWithConversion(const incompatible_char_type* aData, + int32_t aLength = -1); + +#endif // !MOZ_STRING_WITH_OBSOLETE_API + + /** + * Allow this string to be bound to a character buffer + * until the string is rebound or mutated; the caller + * must ensure that the buffer outlives the string. + */ + void Rebind(const char_type* aData, size_type aLength); + + /** + * verify restrictions for dependent strings + */ + void AssertValidDependentString() + { + NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer"); + NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length"); + NS_ASSERTION(mData[mLength] == 0, + "nsTDependentString must wrap only null-terminated strings. " + "You are probably looking for nsTDependentSubstring."); + } + + +protected: + + explicit + nsTString_CharT(uint32_t aFlags) + : substring_type(aFlags) + { + } + + // allow subclasses to initialize fields directly + nsTString_CharT(char_type* aData, size_type aLength, uint32_t aFlags) + : substring_type(aData, aLength, aFlags) + { + } + + struct Segment { + uint32_t mBegin, mLength; + Segment(uint32_t aBegin, uint32_t aLength) + : mBegin(aBegin) + , mLength(aLength) + {} + }; +}; + + +class nsTFixedString_CharT : public nsTString_CharT +{ +public: + + typedef nsTFixedString_CharT self_type; + typedef nsTFixedString_CharT fixed_string_type; + +public: + + /** + * @param aData + * fixed-size buffer to be used by the string (the contents of + * this buffer may be modified by the string) + * @param aStorageSize + * the size of the fixed buffer + * @param aLength (optional) + * the length of the string already contained in the buffer + */ + + nsTFixedString_CharT(char_type* aData, size_type aStorageSize) + : string_type(aData, uint32_t(char_traits::length(aData)), + F_TERMINATED | F_FIXED | F_CLASS_FIXED) + , mFixedCapacity(aStorageSize - 1) + , mFixedBuf(aData) + { + } + + nsTFixedString_CharT(char_type* aData, size_type aStorageSize, + size_type aLength) + : string_type(aData, aLength, F_TERMINATED | F_FIXED | F_CLASS_FIXED) + , mFixedCapacity(aStorageSize - 1) + , mFixedBuf(aData) + { + // null-terminate + mFixedBuf[aLength] = char_type(0); + } + + // |operator=| does not inherit, so we must define our own + self_type& operator=(char_type aChar) + { + Assign(aChar); + return *this; + } + self_type& operator=(const char_type* aData) + { + Assign(aData); + return *this; + } + self_type& operator=(const substring_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_tuple_type& aTuple) + { + Assign(aTuple); + return *this; + } + +protected: + + friend class nsTSubstring_CharT; + + size_type mFixedCapacity; + char_type* mFixedBuf; +}; + + +/** + * nsTAutoString_CharT + * + * Subclass of nsTString_CharT that adds support for stack-based string + * allocation. It is normally not a good idea to use this class on the + * heap, because it will allocate space which may be wasted if the string + * it contains is significantly smaller or any larger than 64 characters. + * + * NAMES: + * nsAutoString for wide characters + * nsAutoCString for narrow characters + */ +class MOZ_NON_MEMMOVABLE nsTAutoString_CharT : public nsTFixedString_CharT +{ +public: + + typedef nsTAutoString_CharT self_type; + +public: + + /** + * constructors + */ + + nsTAutoString_CharT() + : fixed_string_type(mStorage, kDefaultStorageSize, 0) + { + } + + explicit + nsTAutoString_CharT(char_type aChar) + : fixed_string_type(mStorage, kDefaultStorageSize, 0) + { + Assign(aChar); + } + + explicit + nsTAutoString_CharT(const char_type* aData, size_type aLength = size_type(-1)) + : fixed_string_type(mStorage, kDefaultStorageSize, 0) + { + Assign(aData, aLength); + } + +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) + explicit + nsTAutoString_CharT(char16ptr_t aData, size_type aLength = size_type(-1)) + : nsTAutoString_CharT(static_cast<const char16_t*>(aData), aLength) + { + } +#endif + + nsTAutoString_CharT(const self_type& aStr) + : fixed_string_type(mStorage, kDefaultStorageSize, 0) + { + Assign(aStr); + } + + explicit + nsTAutoString_CharT(const substring_type& aStr) + : fixed_string_type(mStorage, kDefaultStorageSize, 0) + { + Assign(aStr); + } + + MOZ_IMPLICIT nsTAutoString_CharT(const substring_tuple_type& aTuple) + : fixed_string_type(mStorage, kDefaultStorageSize, 0) + { + Assign(aTuple); + } + + // |operator=| does not inherit, so we must define our own + self_type& operator=(char_type aChar) + { + Assign(aChar); + return *this; + } + self_type& operator=(const char_type* aData) + { + Assign(aData); + return *this; + } +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) + self_type& operator=(char16ptr_t aStr) + { + Assign(aStr); + return *this; + } +#endif + self_type& operator=(const self_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_tuple_type& aTuple) + { + Assign(aTuple); + return *this; + } + + enum + { + kDefaultStorageSize = 64 + }; + +private: + + char_type mStorage[kDefaultStorageSize]; +}; + + +// +// nsAutoString stores pointers into itself which are invalidated when an +// nsTArray is resized, so nsTArray must not be instantiated with nsAutoString +// elements! +// +template<class E> class nsTArrayElementTraits; +template<> +class nsTArrayElementTraits<nsTAutoString_CharT> +{ +public: + template<class A> struct Dont_Instantiate_nsTArray_of; + template<class A> struct Instead_Use_nsTArray_of; + + static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>* + Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE) + { + return 0; + } + template<class A> + static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>* + Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE, const A& aArg) + { + return 0; + } + static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>* + Destruct(Instead_Use_nsTArray_of<nsTString_CharT>* aE) + { + return 0; + } +}; + +/** + * nsTXPIDLString extends nsTString such that: + * + * (1) mData can be null + * (2) objects of this type can be automatically cast to |const CharT*| + * (3) getter_Copies method is supported to adopt data allocated with + * moz_xmalloc, such as "out string" parameters in XPIDL. + * + * NAMES: + * nsXPIDLString for wide characters + * nsXPIDLCString for narrow characters + */ +class nsTXPIDLString_CharT : public nsTString_CharT +{ +public: + + typedef nsTXPIDLString_CharT self_type; + +public: + + nsTXPIDLString_CharT() + : string_type(char_traits::sEmptyBuffer, 0, F_TERMINATED | F_VOIDED) + { + } + + // copy-constructor required to avoid default + nsTXPIDLString_CharT(const self_type& aStr) + : string_type(char_traits::sEmptyBuffer, 0, F_TERMINATED | F_VOIDED) + { + Assign(aStr); + } + + // return nullptr if we are voided +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) + char16ptr_t get() const +#else + const char_type* get() const +#endif + { + return (mFlags & F_VOIDED) ? nullptr : mData; + } + + // this case operator is the reason why this class cannot just be a + // typedef for nsTString + operator const char_type*() const + { + return get(); + } + + // need this to diambiguous operator[int] + char_type operator[](int32_t aIndex) const + { + return CharAt(index_type(aIndex)); + } + + // |operator=| does not inherit, so we must define our own + self_type& operator=(char_type aChar) + { + Assign(aChar); + return *this; + } + self_type& operator=(const char_type* aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const self_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_tuple_type& aTuple) + { + Assign(aTuple); + return *this; + } +}; + + +/** + * getter_Copies support for use with raw string out params: + * + * NS_IMETHOD GetBlah(char**); + * + * void some_function() + * { + * nsXPIDLCString blah; + * GetBlah(getter_Copies(blah)); + * // ... + * } + */ +class MOZ_STACK_CLASS nsTGetterCopies_CharT +{ +public: + typedef CharT char_type; + + explicit nsTGetterCopies_CharT(nsTSubstring_CharT& aStr) + : mString(aStr) + , mData(nullptr) + { + } + + ~nsTGetterCopies_CharT() + { + mString.Adopt(mData); // OK if mData is null + } + + operator char_type**() + { + return &mData; + } + +private: + nsTSubstring_CharT& mString; + char_type* mData; +}; + +inline nsTGetterCopies_CharT +getter_Copies(nsTSubstring_CharT& aString) +{ + return nsTGetterCopies_CharT(aString); +} + + +/** + * nsTAdoptingString extends nsTXPIDLString such that: + * + * (1) Adopt given string on construction or assignment, i.e. take + * the value of what's given, and make what's given forget its + * value. Note that this class violates constness in a few + * places. Be careful! + */ +class nsTAdoptingString_CharT : public nsTXPIDLString_CharT +{ +public: + + typedef nsTAdoptingString_CharT self_type; + +public: + + explicit nsTAdoptingString_CharT() + { + } + explicit nsTAdoptingString_CharT(char_type* aStr, + size_type aLength = size_type(-1)) + { + Adopt(aStr, aLength); + } + + // copy-constructor required to adopt on copy. Note that this + // will violate the constness of |aStr| in the operator=() + // call. |aStr| will be truncated as a side-effect of this + // constructor. + nsTAdoptingString_CharT(const self_type& aStr) + { + *this = aStr; + } + + // |operator=| does not inherit, so we must define our own + self_type& operator=(const substring_type& aStr) + { + Assign(aStr); + return *this; + } + self_type& operator=(const substring_tuple_type& aTuple) + { + Assign(aTuple); + return *this; + } + + // Adopt(), if possible, when assigning to a self_type&. Note + // that this violates the constness of aStr, aStr is always + // truncated when this operator is called. + self_type& operator=(const self_type& aStr); + +private: + self_type& operator=(const char_type* aData) = delete; + self_type& operator=(char_type* aData) = delete; +}; + |