michael@0: /* vim:set ts=2 sw=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * This header provides wrapper classes around the frozen string API michael@0: * which are roughly equivalent to the internal string classes. michael@0: */ michael@0: michael@0: #ifdef MOZILLA_INTERNAL_API michael@0: #error nsStringAPI.h is only usable from non-MOZILLA_INTERNAL_API code! michael@0: #endif michael@0: michael@0: #ifndef nsStringAPI_h__ michael@0: #define nsStringAPI_h__ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/Char16.h" michael@0: michael@0: #include "nsXPCOMStrings.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "prlog.h" michael@0: #include "nsTArray.h" michael@0: michael@0: /** michael@0: * Comparison function for use with nsACString::Equals michael@0: */ michael@0: NS_HIDDEN_(int32_t) michael@0: CaseInsensitiveCompare(const char *a, const char *b, michael@0: uint32_t length); michael@0: michael@0: class nsAString michael@0: { michael@0: public: michael@0: typedef char16_t char_type; michael@0: typedef nsAString self_type; michael@0: typedef uint32_t size_type; michael@0: typedef uint32_t index_type; michael@0: michael@0: /** michael@0: * Returns the length, beginning, and end of a string in one operation. michael@0: */ michael@0: NS_HIDDEN_(uint32_t) BeginReading(const char_type **begin, michael@0: const char_type **end = nullptr) const; michael@0: michael@0: NS_HIDDEN_(const char_type*) BeginReading() const; michael@0: NS_HIDDEN_(const char_type*) EndReading() const; michael@0: michael@0: NS_HIDDEN_(char_type) CharAt(uint32_t aPos) const michael@0: { michael@0: NS_ASSERTION(aPos < Length(), "Out of bounds"); michael@0: return BeginReading()[aPos]; michael@0: } michael@0: NS_HIDDEN_(char_type) operator [](uint32_t aPos) const michael@0: { michael@0: return CharAt(aPos); michael@0: } michael@0: NS_HIDDEN_(char_type) First() const michael@0: { michael@0: return CharAt(0); michael@0: } michael@0: NS_HIDDEN_(char_type) Last() const michael@0: { michael@0: const char_type* data; michael@0: uint32_t dataLen = NS_StringGetData(*this, &data); michael@0: return data[dataLen - 1]; michael@0: } michael@0: michael@0: /** michael@0: * Get the length, begin writing, and optionally set the length of a michael@0: * string all in one operation. michael@0: * michael@0: * @param newSize Size the string to this length. Pass UINT32_MAX michael@0: * to leave the length unchanged. michael@0: * @return The new length of the string, or 0 if resizing failed. michael@0: */ michael@0: NS_HIDDEN_(uint32_t) BeginWriting(char_type **begin, michael@0: char_type **end = nullptr, michael@0: uint32_t newSize = UINT32_MAX); michael@0: michael@0: NS_HIDDEN_(char_type*) BeginWriting(uint32_t = UINT32_MAX); michael@0: NS_HIDDEN_(char_type*) EndWriting(); michael@0: michael@0: NS_HIDDEN_(bool) SetLength(uint32_t aLen); michael@0: michael@0: NS_HIDDEN_(size_type) Length() const michael@0: { michael@0: const char_type* data; michael@0: return NS_StringGetData(*this, &data); michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) IsEmpty() const michael@0: { michael@0: return Length() == 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(void) SetIsVoid(bool val) michael@0: { michael@0: NS_StringSetIsVoid(*this, val); michael@0: } michael@0: NS_HIDDEN_(bool) IsVoid() const michael@0: { michael@0: return NS_StringGetIsVoid(*this); michael@0: } michael@0: michael@0: NS_HIDDEN_(void) Assign(const self_type& aString) michael@0: { michael@0: NS_StringCopy(*this, aString); michael@0: } michael@0: NS_HIDDEN_(void) Assign(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_StringSetData(*this, aData, aLength); michael@0: } michael@0: NS_HIDDEN_(void) Assign(char_type aChar) michael@0: { michael@0: NS_StringSetData(*this, &aChar, 1); michael@0: } michael@0: #ifdef MOZ_USE_CHAR16_WRAPPER michael@0: NS_HIDDEN_(void) Assign(char16ptr_t aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_StringSetData(*this, aData, aLength); michael@0: } michael@0: #endif michael@0: michael@0: NS_HIDDEN_(void) AssignLiteral(const char *aStr); michael@0: NS_HIDDEN_(void) AssignASCII(const char *aStr) { AssignLiteral(aStr); } michael@0: michael@0: NS_HIDDEN_(self_type&) operator=(const self_type& aString) { Assign(aString); return *this; } michael@0: NS_HIDDEN_(self_type&) operator=(const char_type* aPtr) { Assign(aPtr); return *this; } michael@0: NS_HIDDEN_(self_type&) operator=(char_type aChar) { Assign(aChar); return *this; } michael@0: #ifdef MOZ_USE_CHAR16_WRAPPER michael@0: NS_HIDDEN_(self_type&) operator=(char16ptr_t aPtr) { Assign(aPtr); return *this; } michael@0: #endif michael@0: michael@0: NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) ) michael@0: { michael@0: NS_StringSetDataRange(*this, cutStart, cutLength, data, length); michael@0: } michael@0: NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, char_type c ) michael@0: { michael@0: Replace(cutStart, cutLength, &c, 1); michael@0: } michael@0: NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const self_type& readable ) michael@0: { michael@0: const char_type* data; michael@0: uint32_t dataLen = NS_StringGetData(readable, &data); michael@0: NS_StringSetDataRange(*this, cutStart, cutLength, data, dataLen); michael@0: } michael@0: NS_HIDDEN_(void) SetCharAt( char_type c, index_type pos ) michael@0: { Replace(pos, 1, &c, 1); } michael@0: michael@0: NS_HIDDEN_(void) Append( char_type c ) { Replace(size_type(-1), 0, c); } michael@0: NS_HIDDEN_(void) Append( const char_type* data, size_type length = size_type(-1) ) { Replace(size_type(-1), 0, data, length); } michael@0: #ifdef MOZ_USE_CHAR16_WRAPPER michael@0: NS_HIDDEN_(void) Append( char16ptr_t data, size_type length = size_type(-1) ) { Append(static_cast(data), length); } michael@0: #endif michael@0: NS_HIDDEN_(void) Append( const self_type& readable ) { Replace(size_type(-1), 0, readable); } michael@0: NS_HIDDEN_(void) AppendLiteral( const char *aASCIIStr ); michael@0: NS_HIDDEN_(void) AppendASCII( const char *aASCIIStr ) { AppendLiteral(aASCIIStr); } michael@0: michael@0: NS_HIDDEN_(self_type&) operator+=( char_type c ) { Append(c); return *this; } michael@0: NS_HIDDEN_(self_type&) operator+=( const char_type* data ) { Append(data); return *this; } michael@0: NS_HIDDEN_(self_type&) operator+=( const self_type& readable ) { Append(readable); return *this; } michael@0: michael@0: NS_HIDDEN_(void) Insert( char_type c, index_type pos ) { Replace(pos, 0, c); } michael@0: NS_HIDDEN_(void) Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); } michael@0: NS_HIDDEN_(void) Insert( const self_type& readable, index_type pos ) { Replace(pos, 0, readable); } michael@0: michael@0: NS_HIDDEN_(void) Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, nullptr, 0); } michael@0: michael@0: NS_HIDDEN_(void) Truncate() { SetLength(0); } michael@0: michael@0: /** michael@0: * Remove all occurences of characters in aSet from the string. michael@0: */ michael@0: NS_HIDDEN_(void) StripChars(const char *aSet); michael@0: michael@0: /** michael@0: * Strip whitespace characters from the string. michael@0: */ michael@0: NS_HIDDEN_(void) StripWhitespace() { StripChars("\b\t\r\n "); } michael@0: michael@0: NS_HIDDEN_(void) Trim(const char *aSet, bool aLeading = true, michael@0: bool aTrailing = true); michael@0: michael@0: /** michael@0: * Compare strings of characters. Return 0 if the characters are equal, michael@0: */ michael@0: typedef int32_t (*ComparatorFunc)(const char_type *a, michael@0: const char_type *b, michael@0: uint32_t length); michael@0: michael@0: static NS_HIDDEN_(int32_t) DefaultComparator(const char_type *a, michael@0: const char_type *b, michael@0: uint32_t length); michael@0: michael@0: NS_HIDDEN_(int32_t) Compare( const char_type *other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(int32_t) Compare( const self_type &other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(bool) Equals( const char_type *other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(bool) Equals( const self_type &other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(bool) operator < (const self_type &other) const michael@0: { michael@0: return Compare(other) < 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator < (const char_type *other) const michael@0: { michael@0: return Compare(other) < 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator <= (const self_type &other) const michael@0: { michael@0: return Compare(other) <= 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator <= (const char_type *other) const michael@0: { michael@0: return Compare(other) <= 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator == (const self_type &other) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: NS_HIDDEN_(bool) operator == (const char_type *other) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: #ifdef MOZ_USE_CHAR16_WRAPPER michael@0: NS_HIDDEN_(bool) operator == (char16ptr_t other) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: #endif michael@0: michael@0: NS_HIDDEN_(bool) operator >= (const self_type &other) const michael@0: { michael@0: return Compare(other) >= 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator >= (const char_type *other) const michael@0: { michael@0: return Compare(other) >= 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator > (const self_type &other) const michael@0: { michael@0: return Compare(other) > 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator > (const char_type *other) const michael@0: { michael@0: return Compare(other) > 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator != (const self_type &other) const michael@0: { michael@0: return !Equals(other); michael@0: } michael@0: NS_HIDDEN_(bool) operator != (const char_type *other) const michael@0: { michael@0: return !Equals(other); michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) EqualsLiteral(const char *aASCIIString) const; michael@0: NS_HIDDEN_(bool) EqualsASCII(const char *aASCIIString) const michael@0: { michael@0: return EqualsLiteral(aASCIIString); michael@0: } michael@0: michael@0: /** michael@0: * Case-insensitive match this string to a lowercase ASCII string. michael@0: */ michael@0: NS_HIDDEN_(bool) LowerCaseEqualsLiteral(const char *aASCIIString) const; michael@0: michael@0: /** michael@0: * Find the first occurrence of aStr in this string. michael@0: * michael@0: * @return the offset of aStr, or -1 if not found michael@0: */ michael@0: NS_HIDDEN_(int32_t) Find(const self_type& aStr, michael@0: ComparatorFunc c = DefaultComparator) const michael@0: { return Find(aStr, 0, c); } michael@0: michael@0: /** michael@0: * Find the first occurrence of aStr in this string, beginning at aOffset. michael@0: * michael@0: * @return the offset of aStr, or -1 if not found michael@0: */ michael@0: NS_HIDDEN_(int32_t) Find(const self_type& aStr, uint32_t aOffset, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Find an ASCII string within this string. michael@0: * michael@0: * @return the offset of aStr, or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) Find(const char *aStr, bool aIgnoreCase = false) const michael@0: { return Find(aStr, 0, aIgnoreCase); } michael@0: michael@0: NS_HIDDEN_(int32_t) Find(const char *aStr, uint32_t aOffset, bool aIgnoreCase = false) const; michael@0: michael@0: /** michael@0: * Find the last occurrence of aStr in this string. michael@0: * michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const self_type& aStr, michael@0: ComparatorFunc c = DefaultComparator) const michael@0: { return RFind(aStr, -1, c); } michael@0: michael@0: /** michael@0: * Find the last occurrence of aStr in this string, beginning at aOffset. michael@0: * michael@0: * @param aOffset the offset from the beginning of the string to begin michael@0: * searching. If aOffset < 0, search from end of this string. michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const self_type& aStr, int32_t aOffset, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Find the last occurrence of an ASCII string within this string. michael@0: * michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const char *aStr, bool aIgnoreCase = false) const michael@0: { return RFind(aStr, -1, aIgnoreCase); } michael@0: michael@0: /** michael@0: * Find the last occurrence of an ASCII string beginning at aOffset. michael@0: * michael@0: * @param aOffset the offset from the beginning of the string to begin michael@0: * searching. If aOffset < 0, search from end of this string. michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const char *aStr, int32_t aOffset, bool aIgnoreCase) const; michael@0: michael@0: /** michael@0: * Search for the offset of the first occurrence of a character in a michael@0: * string. michael@0: * michael@0: * @param aOffset the offset from the beginning of the string to begin michael@0: * searching michael@0: * @return The offset of the character from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) FindChar(char_type aChar, uint32_t aOffset = 0) const; michael@0: michael@0: /** michael@0: * Search for the offset of the last occurrence of a character in a michael@0: * string. michael@0: * michael@0: * @return The offset of the character from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFindChar(char_type aChar) const; michael@0: michael@0: /** michael@0: * Append a string representation of a number. michael@0: */ michael@0: NS_HIDDEN_(void) AppendInt(int aInt, int32_t aRadix = 10); michael@0: michael@0: #ifndef XPCOM_GLUE_AVOID_NSPR michael@0: /** michael@0: * Convert this string to an integer. michael@0: * michael@0: * @param aErrorCode pointer to contain result code. michael@0: * @param aRadix must be 10 or 16 michael@0: */ michael@0: NS_HIDDEN_(int32_t) ToInteger(nsresult* aErrorCode, michael@0: uint32_t aRadix = 10) const; michael@0: /** michael@0: * Convert this string to a 64-bit integer. michael@0: * michael@0: * @param aErrorCode pointer to contain result code. michael@0: * @param aRadix must be 10 or 16 michael@0: */ michael@0: NS_HIDDEN_(int64_t) ToInteger64(nsresult* aErrorCode, michael@0: uint32_t aRadix = 10) const; michael@0: #endif // XPCOM_GLUE_AVOID_NSPR michael@0: michael@0: protected: michael@0: // Prevent people from allocating a nsAString directly. michael@0: ~nsAString() {} michael@0: }; michael@0: michael@0: class nsACString michael@0: { michael@0: public: michael@0: typedef char char_type; michael@0: typedef nsACString self_type; michael@0: typedef uint32_t size_type; michael@0: typedef uint32_t index_type; michael@0: michael@0: /** michael@0: * Returns the length, beginning, and end of a string in one operation. michael@0: */ michael@0: NS_HIDDEN_(uint32_t) BeginReading(const char_type **begin, michael@0: const char_type **end = nullptr) const; michael@0: michael@0: NS_HIDDEN_(const char_type*) BeginReading() const; michael@0: NS_HIDDEN_(const char_type*) EndReading() const; michael@0: michael@0: NS_HIDDEN_(char_type) CharAt(uint32_t aPos) const michael@0: { michael@0: NS_ASSERTION(aPos < Length(), "Out of bounds"); michael@0: return BeginReading()[aPos]; michael@0: } michael@0: NS_HIDDEN_(char_type) operator [](uint32_t aPos) const michael@0: { michael@0: return CharAt(aPos); michael@0: } michael@0: NS_HIDDEN_(char_type) First() const michael@0: { michael@0: return CharAt(0); michael@0: } michael@0: NS_HIDDEN_(char_type) Last() const michael@0: { michael@0: const char_type* data; michael@0: uint32_t dataLen = NS_CStringGetData(*this, &data); michael@0: return data[dataLen - 1]; michael@0: } michael@0: michael@0: /** michael@0: * Get the length, begin writing, and optionally set the length of a michael@0: * string all in one operation. michael@0: * michael@0: * @param newSize Size the string to this length. Pass UINT32_MAX michael@0: * to leave the length unchanged. michael@0: * @return The new length of the string, or 0 if resizing failed. michael@0: */ michael@0: NS_HIDDEN_(uint32_t) BeginWriting(char_type **begin, michael@0: char_type **end = nullptr, michael@0: uint32_t newSize = UINT32_MAX); michael@0: michael@0: NS_HIDDEN_(char_type*) BeginWriting(uint32_t aLen = UINT32_MAX); michael@0: NS_HIDDEN_(char_type*) EndWriting(); michael@0: michael@0: NS_HIDDEN_(bool) SetLength(uint32_t aLen); michael@0: michael@0: NS_HIDDEN_(size_type) Length() const michael@0: { michael@0: const char_type* data; michael@0: return NS_CStringGetData(*this, &data); michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) IsEmpty() const michael@0: { michael@0: return Length() == 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(void) SetIsVoid(bool val) michael@0: { michael@0: NS_CStringSetIsVoid(*this, val); michael@0: } michael@0: NS_HIDDEN_(bool) IsVoid() const michael@0: { michael@0: return NS_CStringGetIsVoid(*this); michael@0: } michael@0: michael@0: NS_HIDDEN_(void) Assign(const self_type& aString) michael@0: { michael@0: NS_CStringCopy(*this, aString); michael@0: } michael@0: NS_HIDDEN_(void) Assign(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_CStringSetData(*this, aData, aLength); michael@0: } michael@0: NS_HIDDEN_(void) Assign(char_type aChar) michael@0: { michael@0: NS_CStringSetData(*this, &aChar, 1); michael@0: } michael@0: NS_HIDDEN_(void) AssignLiteral(const char_type *aData) michael@0: { michael@0: Assign(aData); michael@0: } michael@0: NS_HIDDEN_(void) AssignASCII(const char_type *aData) michael@0: { michael@0: Assign(aData); michael@0: } michael@0: michael@0: NS_HIDDEN_(self_type&) operator=(const self_type& aString) { Assign(aString); return *this; } michael@0: NS_HIDDEN_(self_type&) operator=(const char_type* aPtr) { Assign(aPtr); return *this; } michael@0: NS_HIDDEN_(self_type&) operator=(char_type aChar) { Assign(aChar); return *this; } michael@0: michael@0: NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) ) michael@0: { michael@0: NS_CStringSetDataRange(*this, cutStart, cutLength, data, length); michael@0: } michael@0: NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, char_type c ) michael@0: { michael@0: Replace(cutStart, cutLength, &c, 1); michael@0: } michael@0: NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const self_type& readable ) michael@0: { michael@0: const char_type* data; michael@0: uint32_t dataLen = NS_CStringGetData(readable, &data); michael@0: NS_CStringSetDataRange(*this, cutStart, cutLength, data, dataLen); michael@0: } michael@0: NS_HIDDEN_(void) SetCharAt( char_type c, index_type pos ) michael@0: { Replace(pos, 1, &c, 1); } michael@0: michael@0: NS_HIDDEN_(void) Append( char_type c ) { Replace(size_type(-1), 0, c); } michael@0: NS_HIDDEN_(void) Append( const char_type* data, size_type length = size_type(-1) ) { Replace(size_type(-1), 0, data, length); } michael@0: NS_HIDDEN_(void) Append( const self_type& readable ) { Replace(size_type(-1), 0, readable); } michael@0: NS_HIDDEN_(void) AppendLiteral( const char *aASCIIStr ) { Append(aASCIIStr); } michael@0: NS_HIDDEN_(void) AppendASCII( const char *aASCIIStr ) { Append(aASCIIStr); } michael@0: michael@0: NS_HIDDEN_(self_type&) operator+=( char_type c ) { Append(c); return *this; } michael@0: NS_HIDDEN_(self_type&) operator+=( const char_type* data ) { Append(data); return *this; } michael@0: NS_HIDDEN_(self_type&) operator+=( const self_type& readable ) { Append(readable); return *this; } michael@0: michael@0: NS_HIDDEN_(void) Insert( char_type c, index_type pos ) { Replace(pos, 0, c); } michael@0: NS_HIDDEN_(void) Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); } michael@0: NS_HIDDEN_(void) Insert( const self_type& readable, index_type pos ) { Replace(pos, 0, readable); } michael@0: michael@0: NS_HIDDEN_(void) Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, nullptr, 0); } michael@0: michael@0: NS_HIDDEN_(void) Truncate() { SetLength(0); } michael@0: michael@0: /** michael@0: * Remove all occurences of characters in aSet from the string. michael@0: */ michael@0: NS_HIDDEN_(void) StripChars(const char *aSet); michael@0: michael@0: /** michael@0: * Strip whitespace characters from the string. michael@0: */ michael@0: NS_HIDDEN_(void) StripWhitespace() { StripChars("\b\t\r\n "); } michael@0: michael@0: NS_HIDDEN_(void) Trim(const char *aSet, bool aLeading = true, michael@0: bool aTrailing = true); michael@0: michael@0: /** michael@0: * Compare strings of characters. Return 0 if the characters are equal, michael@0: */ michael@0: typedef int32_t (*ComparatorFunc)(const char_type *a, michael@0: const char_type *b, michael@0: uint32_t length); michael@0: michael@0: static NS_HIDDEN_(int32_t) DefaultComparator(const char_type *a, michael@0: const char_type *b, michael@0: uint32_t length); michael@0: michael@0: NS_HIDDEN_(int32_t) Compare( const char_type *other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(int32_t) Compare( const self_type &other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(bool) Equals( const char_type *other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(bool) Equals( const self_type &other, michael@0: ComparatorFunc c = DefaultComparator ) const; michael@0: michael@0: NS_HIDDEN_(bool) operator < (const self_type &other) const michael@0: { michael@0: return Compare(other) < 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator < (const char_type *other) const michael@0: { michael@0: return Compare(other) < 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator <= (const self_type &other) const michael@0: { michael@0: return Compare(other) <= 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator <= (const char_type *other) const michael@0: { michael@0: return Compare(other) <= 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator == (const self_type &other) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: NS_HIDDEN_(bool) operator == (const char_type *other) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator >= (const self_type &other) const michael@0: { michael@0: return Compare(other) >= 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator >= (const char_type *other) const michael@0: { michael@0: return Compare(other) >= 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator > (const self_type &other) const michael@0: { michael@0: return Compare(other) > 0; michael@0: } michael@0: NS_HIDDEN_(bool) operator > (const char_type *other) const michael@0: { michael@0: return Compare(other) > 0; michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) operator != (const self_type &other) const michael@0: { michael@0: return !Equals(other); michael@0: } michael@0: NS_HIDDEN_(bool) operator != (const char_type *other) const michael@0: { michael@0: return !Equals(other); michael@0: } michael@0: michael@0: NS_HIDDEN_(bool) EqualsLiteral( const char_type *other ) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: NS_HIDDEN_(bool) EqualsASCII( const char_type *other ) const michael@0: { michael@0: return Equals(other); michael@0: } michael@0: michael@0: /** michael@0: * Case-insensitive match this string to a lowercase ASCII string. michael@0: */ michael@0: NS_HIDDEN_(bool) LowerCaseEqualsLiteral(const char *aASCIIString) const michael@0: { michael@0: return Equals(aASCIIString, CaseInsensitiveCompare); michael@0: } michael@0: michael@0: /** michael@0: * Find the first occurrence of aStr in this string. michael@0: * michael@0: * @return the offset of aStr, or -1 if not found michael@0: */ michael@0: NS_HIDDEN_(int32_t) Find(const self_type& aStr, michael@0: ComparatorFunc c = DefaultComparator) const michael@0: { return Find(aStr, 0, c); } michael@0: michael@0: /** michael@0: * Find the first occurrence of aStr in this string, beginning at aOffset. michael@0: * michael@0: * @return the offset of aStr, or -1 if not found michael@0: */ michael@0: NS_HIDDEN_(int32_t) Find(const self_type& aStr, uint32_t aOffset, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Find the first occurrence of aStr in this string. michael@0: * michael@0: * @return the offset of aStr, or -1 if not found michael@0: */ michael@0: NS_HIDDEN_(int32_t) Find(const char_type *aStr, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: NS_HIDDEN_(int32_t) Find(const char_type *aStr, uint32_t aLen, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Find the last occurrence of aStr in this string. michael@0: * michael@0: * @return The offset of the character from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const self_type& aStr, michael@0: ComparatorFunc c = DefaultComparator) const michael@0: { return RFind(aStr, -1, c); } michael@0: michael@0: /** michael@0: * Find the last occurrence of aStr in this string, beginning at aOffset. michael@0: * michael@0: * @param aOffset the offset from the beginning of the string to begin michael@0: * searching. If aOffset < 0, search from end of this string. michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const self_type& aStr, int32_t aOffset, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Find the last occurrence of aStr in this string. michael@0: * michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const char_type *aStr, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Find the last occurrence of an ASCII string in this string, michael@0: * beginning at aOffset. michael@0: * michael@0: * @param aLen is the length of aStr michael@0: * @return The offset of aStr from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFind(const char_type *aStr, int32_t aLen, michael@0: ComparatorFunc c = DefaultComparator) const; michael@0: michael@0: /** michael@0: * Search for the offset of the first occurrence of a character in a michael@0: * string. michael@0: * michael@0: * @param aOffset the offset from the beginning of the string to begin michael@0: * searching michael@0: * @return The offset of the character from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) FindChar(char_type aChar, uint32_t aOffset = 0) const; michael@0: michael@0: /** michael@0: * Search for the offset of the last occurrence of a character in a michael@0: * string. michael@0: * michael@0: * @return The offset of the character from the beginning of the string, michael@0: * or -1 if not found. michael@0: */ michael@0: NS_HIDDEN_(int32_t) RFindChar(char_type aChar) const; michael@0: michael@0: /** michael@0: * Append a string representation of a number. michael@0: */ michael@0: NS_HIDDEN_(void) AppendInt(int aInt, int32_t aRadix = 10); michael@0: michael@0: #ifndef XPCOM_GLUE_AVOID_NSPR michael@0: /** michael@0: * Convert this string to an integer. michael@0: * michael@0: * @param aErrorCode pointer to contain result code. michael@0: * @param aRadix must be 10 or 16 michael@0: */ michael@0: NS_HIDDEN_(int32_t) ToInteger(nsresult* aErrorCode, michael@0: uint32_t aRadix = 10) const; michael@0: /** michael@0: * Convert this string to a 64-bit integer. michael@0: * michael@0: * @param aErrorCode pointer to contain result code. michael@0: * @param aRadix must be 10 or 16 michael@0: */ michael@0: NS_HIDDEN_(int64_t) ToInteger64(nsresult* aErrorCode, michael@0: uint32_t aRadix = 10) const; michael@0: #endif // XPCOM_GLUE_AVOID_NSPR michael@0: michael@0: protected: michael@0: // Prevent people from allocating a nsAString directly. michael@0: ~nsACString() {} michael@0: }; michael@0: michael@0: /* ------------------------------------------------------------------------- */ michael@0: michael@0: /** michael@0: * Below we define nsStringContainer and nsCStringContainer. These classes michael@0: * have unspecified structure. In most cases, your code should use michael@0: * nsString/nsCString instead of these classes; if you prefer C-style michael@0: * programming, then look no further. michael@0: */ michael@0: michael@0: class nsStringContainer : public nsAString, michael@0: private nsStringContainer_base michael@0: { michael@0: }; michael@0: michael@0: class nsCStringContainer : public nsACString, michael@0: private nsStringContainer_base michael@0: { michael@0: }; michael@0: michael@0: /** michael@0: * The following classes are C++ helper classes that make the frozen string michael@0: * API easier to use. michael@0: */ michael@0: michael@0: /** michael@0: * Rename symbols to avoid conflicting with internal versions. michael@0: */ michael@0: #define nsString nsString_external michael@0: #define nsCString nsCString_external michael@0: #define nsDependentString nsDependentString_external michael@0: #define nsDependentCString nsDependentCString_external michael@0: #define NS_ConvertASCIItoUTF16 NS_ConvertASCIItoUTF16_external michael@0: #define NS_ConvertUTF8toUTF16 NS_ConvertUTF8toUTF16_external michael@0: #define NS_ConvertUTF16toUTF8 NS_ConvertUTF16toUTF8_external michael@0: #define NS_LossyConvertUTF16toASCII NS_LossyConvertUTF16toASCII_external michael@0: #define nsGetterCopies nsGetterCopies_external michael@0: #define nsCGetterCopies nsCGetterCopies_external michael@0: #define nsDependentSubstring nsDependentSubstring_external michael@0: #define nsDependentCSubstring nsDependentCSubstring_external michael@0: michael@0: /** michael@0: * basic strings michael@0: */ michael@0: michael@0: class nsString : public nsStringContainer michael@0: { michael@0: public: michael@0: typedef nsString self_type; michael@0: typedef nsAString abstract_string_type; michael@0: michael@0: nsString() michael@0: { michael@0: NS_StringContainerInit(*this); michael@0: } michael@0: michael@0: nsString(const self_type& aString) michael@0: { michael@0: NS_StringContainerInit(*this); michael@0: NS_StringCopy(*this, aString); michael@0: } michael@0: michael@0: explicit michael@0: nsString(const abstract_string_type& aReadable) michael@0: { michael@0: NS_StringContainerInit(*this); michael@0: NS_StringCopy(*this, aReadable); michael@0: } michael@0: michael@0: explicit michael@0: nsString(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_StringContainerInit2(*this, aData, aLength, 0); michael@0: } michael@0: michael@0: #ifdef MOZ_USE_CHAR16_WRAPPER michael@0: explicit michael@0: nsString(char16ptr_t aData, size_type aLength = UINT32_MAX) michael@0: : nsString(static_cast(aData), aLength) {} michael@0: #endif michael@0: michael@0: ~nsString() michael@0: { michael@0: NS_StringContainerFinish(*this); michael@0: } michael@0: michael@0: char16ptr_t get() const michael@0: { michael@0: return char16ptr_t(BeginReading()); michael@0: } michael@0: michael@0: self_type& operator=(const self_type& aString) { Assign(aString); return *this; } michael@0: self_type& operator=(const abstract_string_type& aReadable) { Assign(aReadable); return *this; } michael@0: self_type& operator=(const char_type* aPtr) { Assign(aPtr); return *this; } michael@0: self_type& operator=(char_type aChar) { Assign(aChar); return *this; } michael@0: michael@0: void Adopt(const char_type *aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_StringContainerFinish(*this); michael@0: NS_StringContainerInit2(*this, aData, aLength, michael@0: NS_STRING_CONTAINER_INIT_ADOPT); michael@0: } michael@0: michael@0: protected: michael@0: michael@0: nsString(const char_type* aData, size_type aLength, uint32_t aFlags) michael@0: { michael@0: NS_StringContainerInit2(*this, aData, aLength, aFlags); michael@0: } michael@0: }; michael@0: michael@0: class nsCString : public nsCStringContainer michael@0: { michael@0: public: michael@0: typedef nsCString self_type; michael@0: typedef nsACString abstract_string_type; michael@0: michael@0: nsCString() michael@0: { michael@0: NS_CStringContainerInit(*this); michael@0: } michael@0: michael@0: nsCString(const self_type& aString) michael@0: { michael@0: NS_CStringContainerInit(*this); michael@0: NS_CStringCopy(*this, aString); michael@0: } michael@0: michael@0: explicit michael@0: nsCString(const abstract_string_type& aReadable) michael@0: { michael@0: NS_CStringContainerInit(*this); michael@0: NS_CStringCopy(*this, aReadable); michael@0: } michael@0: michael@0: explicit michael@0: nsCString(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_CStringContainerInit(*this); michael@0: NS_CStringSetData(*this, aData, aLength); michael@0: } michael@0: michael@0: ~nsCString() michael@0: { michael@0: NS_CStringContainerFinish(*this); michael@0: } michael@0: michael@0: const char_type* get() const michael@0: { michael@0: return BeginReading(); michael@0: } michael@0: michael@0: self_type& operator=(const self_type& aString) { Assign(aString); return *this; } michael@0: self_type& operator=(const abstract_string_type& aReadable) { Assign(aReadable); return *this; } michael@0: self_type& operator=(const char_type* aPtr) { Assign(aPtr); return *this; } michael@0: self_type& operator=(char_type aChar) { Assign(aChar); return *this; } michael@0: michael@0: void Adopt(const char_type *aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_CStringContainerFinish(*this); michael@0: NS_CStringContainerInit2(*this, aData, aLength, michael@0: NS_CSTRING_CONTAINER_INIT_ADOPT); michael@0: } michael@0: michael@0: protected: michael@0: michael@0: nsCString(const char_type* aData, size_type aLength, uint32_t aFlags) michael@0: { michael@0: NS_CStringContainerInit2(*this, aData, aLength, aFlags); michael@0: } michael@0: }; michael@0: michael@0: michael@0: /** michael@0: * dependent strings michael@0: */ michael@0: michael@0: class nsDependentString : public nsString michael@0: { michael@0: public: michael@0: typedef nsDependentString self_type; michael@0: michael@0: nsDependentString() {} michael@0: michael@0: explicit michael@0: nsDependentString(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: : nsString(aData, aLength, NS_CSTRING_CONTAINER_INIT_DEPEND) michael@0: {} michael@0: michael@0: #ifdef MOZ_USE_CHAR16_WRAPPER michael@0: explicit michael@0: nsDependentString(char16ptr_t aData, size_type aLength = UINT32_MAX) michael@0: : nsDependentString(static_cast(aData), aLength) michael@0: {} michael@0: #endif michael@0: michael@0: void Rebind(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_StringContainerFinish(*this); michael@0: NS_StringContainerInit2(*this, aData, aLength, michael@0: NS_STRING_CONTAINER_INIT_DEPEND); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: class nsDependentCString : public nsCString michael@0: { michael@0: public: michael@0: typedef nsDependentCString self_type; michael@0: michael@0: nsDependentCString() {} michael@0: michael@0: explicit michael@0: nsDependentCString(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: : nsCString(aData, aLength, NS_CSTRING_CONTAINER_INIT_DEPEND) michael@0: {} michael@0: michael@0: void Rebind(const char_type* aData, size_type aLength = UINT32_MAX) michael@0: { michael@0: NS_CStringContainerFinish(*this); michael@0: NS_CStringContainerInit2(*this, aData, aLength, michael@0: NS_CSTRING_CONTAINER_INIT_DEPEND); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: michael@0: /** michael@0: * conversion classes michael@0: */ michael@0: michael@0: inline void michael@0: CopyUTF16toUTF8(const nsAString& aSource, nsACString& aDest) michael@0: { michael@0: NS_UTF16ToCString(aSource, NS_CSTRING_ENCODING_UTF8, aDest); michael@0: } michael@0: michael@0: inline void michael@0: CopyUTF8toUTF16(const nsACString& aSource, nsAString& aDest) michael@0: { michael@0: NS_CStringToUTF16(aSource, NS_CSTRING_ENCODING_UTF8, aDest); michael@0: } michael@0: michael@0: inline void michael@0: LossyCopyUTF16toASCII(const nsAString& aSource, nsACString& aDest) michael@0: { michael@0: NS_UTF16ToCString(aSource, NS_CSTRING_ENCODING_ASCII, aDest); michael@0: } michael@0: michael@0: inline void michael@0: CopyASCIItoUTF16(const nsACString& aSource, nsAString& aDest) michael@0: { michael@0: NS_CStringToUTF16(aSource, NS_CSTRING_ENCODING_ASCII, aDest); michael@0: } michael@0: michael@0: NS_COM_GLUE char* michael@0: ToNewUTF8String(const nsAString& aSource); michael@0: michael@0: class NS_ConvertASCIItoUTF16 : public nsString michael@0: { michael@0: public: michael@0: typedef NS_ConvertASCIItoUTF16 self_type; michael@0: michael@0: explicit michael@0: NS_ConvertASCIItoUTF16(const nsACString& aStr) michael@0: { michael@0: NS_CStringToUTF16(aStr, NS_CSTRING_ENCODING_ASCII, *this); michael@0: } michael@0: michael@0: explicit michael@0: NS_ConvertASCIItoUTF16(const char* aData, uint32_t aLength = UINT32_MAX) michael@0: { michael@0: NS_CStringToUTF16(nsDependentCString(aData, aLength), michael@0: NS_CSTRING_ENCODING_ASCII, *this); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: class NS_ConvertUTF8toUTF16 : public nsString michael@0: { michael@0: public: michael@0: typedef NS_ConvertUTF8toUTF16 self_type; michael@0: michael@0: explicit michael@0: NS_ConvertUTF8toUTF16(const nsACString& aStr) michael@0: { michael@0: NS_CStringToUTF16(aStr, NS_CSTRING_ENCODING_UTF8, *this); michael@0: } michael@0: michael@0: explicit michael@0: NS_ConvertUTF8toUTF16(const char* aData, uint32_t aLength = UINT32_MAX) michael@0: { michael@0: NS_CStringToUTF16(nsDependentCString(aData, aLength), michael@0: NS_CSTRING_ENCODING_UTF8, *this); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: class NS_ConvertUTF16toUTF8 : public nsCString michael@0: { michael@0: public: michael@0: typedef NS_ConvertUTF16toUTF8 self_type; michael@0: michael@0: explicit michael@0: NS_ConvertUTF16toUTF8(const nsAString& aStr) michael@0: { michael@0: NS_UTF16ToCString(aStr, NS_CSTRING_ENCODING_UTF8, *this); michael@0: } michael@0: michael@0: explicit michael@0: NS_ConvertUTF16toUTF8(const char16_t* aData, uint32_t aLength = UINT32_MAX) michael@0: { michael@0: NS_UTF16ToCString(nsDependentString(aData, aLength), michael@0: NS_CSTRING_ENCODING_UTF8, *this); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: class NS_LossyConvertUTF16toASCII : public nsCString michael@0: { michael@0: public: michael@0: typedef NS_LossyConvertUTF16toASCII self_type; michael@0: michael@0: explicit michael@0: NS_LossyConvertUTF16toASCII(const nsAString& aStr) michael@0: { michael@0: NS_UTF16ToCString(aStr, NS_CSTRING_ENCODING_ASCII, *this); michael@0: } michael@0: michael@0: explicit michael@0: NS_LossyConvertUTF16toASCII(const char16_t* aData, uint32_t aLength = UINT32_MAX) michael@0: { michael@0: NS_UTF16ToCString(nsDependentString(aData, aLength), michael@0: NS_CSTRING_ENCODING_ASCII, *this); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: michael@0: /** michael@0: * literal strings michael@0: */ michael@0: static_assert(sizeof(char16_t) == 2, "size of char16_t must be 2"); michael@0: static_assert(char16_t(-1) > char16_t(0), "char16_t must be unsigned"); michael@0: michael@0: #define NS_MULTILINE_LITERAL_STRING(s) nsDependentString(reinterpret_cast(s), uint32_t((sizeof(s)/2)-1)) michael@0: #define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(reinterpret_cast(s), uint32_t((sizeof(s)/2)-1)) michael@0: #define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsDependentString n(reinterpret_cast(s), uint32_t((sizeof(s)/2)-1)) michael@0: typedef nsDependentString nsLiteralString; michael@0: michael@0: /* Check that char16_t is unsigned */ michael@0: static_assert(char16_t(-1) > char16_t(0), "char16_t is by definition an unsigned type"); michael@0: michael@0: #define NS_LITERAL_STRING(s) static_cast(NS_MULTILINE_LITERAL_STRING(MOZ_UTF16(s))) michael@0: #define NS_LITERAL_STRING_INIT(n,s) NS_MULTILINE_LITERAL_STRING_INIT(n, MOZ_UTF16(s)) michael@0: #define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n, MOZ_UTF16(s)) michael@0: michael@0: #define NS_LITERAL_CSTRING(s) static_cast(nsDependentCString(s, uint32_t(sizeof(s)-1))) michael@0: #define NS_LITERAL_CSTRING_INIT(n,s) n(s, uint32_t(sizeof(s)-1)) michael@0: #define NS_NAMED_LITERAL_CSTRING(n,s) const nsDependentCString n(s, uint32_t(sizeof(s)-1)) michael@0: michael@0: typedef nsDependentCString nsLiteralCString; michael@0: michael@0: michael@0: /** michael@0: * getter_Copies support michael@0: * michael@0: * NS_IMETHOD GetBlah(char16_t**); michael@0: * michael@0: * void some_function() michael@0: * { michael@0: * nsString blah; michael@0: * GetBlah(getter_Copies(blah)); michael@0: * // ... michael@0: * } michael@0: */ michael@0: michael@0: class nsGetterCopies michael@0: { michael@0: public: michael@0: typedef char16_t char_type; michael@0: michael@0: nsGetterCopies(nsString& aStr) michael@0: : mString(aStr), mData(nullptr) michael@0: {} michael@0: michael@0: ~nsGetterCopies() michael@0: { michael@0: mString.Adopt(mData); michael@0: } michael@0: michael@0: operator char_type**() michael@0: { michael@0: return &mData; michael@0: } michael@0: michael@0: private: michael@0: nsString& mString; michael@0: char_type* mData; michael@0: }; michael@0: michael@0: inline nsGetterCopies michael@0: getter_Copies(nsString& aString) michael@0: { michael@0: return nsGetterCopies(aString); michael@0: } michael@0: michael@0: class nsCGetterCopies michael@0: { michael@0: public: michael@0: typedef char char_type; michael@0: michael@0: nsCGetterCopies(nsCString& aStr) michael@0: : mString(aStr), mData(nullptr) michael@0: {} michael@0: michael@0: ~nsCGetterCopies() michael@0: { michael@0: mString.Adopt(mData); michael@0: } michael@0: michael@0: operator char_type**() michael@0: { michael@0: return &mData; michael@0: } michael@0: michael@0: private: michael@0: nsCString& mString; michael@0: char_type* mData; michael@0: }; michael@0: michael@0: inline nsCGetterCopies michael@0: getter_Copies(nsCString& aString) michael@0: { michael@0: return nsCGetterCopies(aString); michael@0: } michael@0: michael@0: michael@0: /** michael@0: * substrings michael@0: */ michael@0: michael@0: class NS_COM_GLUE nsDependentSubstring : public nsStringContainer michael@0: { michael@0: public: michael@0: typedef nsDependentSubstring self_type; michael@0: typedef nsAString abstract_string_type; michael@0: michael@0: ~nsDependentSubstring() michael@0: { michael@0: NS_StringContainerFinish(*this); michael@0: } michael@0: michael@0: nsDependentSubstring() michael@0: { michael@0: NS_StringContainerInit(*this); michael@0: } michael@0: michael@0: nsDependentSubstring(const char_type *aStart, uint32_t aLength) michael@0: { michael@0: NS_StringContainerInit2(*this, aStart, aLength, michael@0: NS_STRING_CONTAINER_INIT_DEPEND | michael@0: NS_STRING_CONTAINER_INIT_SUBSTRING); michael@0: } michael@0: michael@0: nsDependentSubstring(const abstract_string_type& aStr, michael@0: uint32_t aStartPos); michael@0: nsDependentSubstring(const abstract_string_type& aStr, michael@0: uint32_t aStartPos, uint32_t aLength); michael@0: michael@0: void Rebind(const char_type *aStart, uint32_t aLength) michael@0: { michael@0: NS_StringContainerFinish(*this); michael@0: NS_StringContainerInit2(*this, aStart, aLength, michael@0: NS_STRING_CONTAINER_INIT_DEPEND | michael@0: NS_STRING_CONTAINER_INIT_SUBSTRING); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: class NS_COM_GLUE nsDependentCSubstring : public nsCStringContainer michael@0: { michael@0: public: michael@0: typedef nsDependentCSubstring self_type; michael@0: typedef nsACString abstract_string_type; michael@0: michael@0: ~nsDependentCSubstring() michael@0: { michael@0: NS_CStringContainerFinish(*this); michael@0: } michael@0: michael@0: nsDependentCSubstring() michael@0: { michael@0: NS_CStringContainerInit(*this); michael@0: } michael@0: michael@0: nsDependentCSubstring(const char_type *aStart, uint32_t aLength) michael@0: { michael@0: NS_CStringContainerInit2(*this, aStart, aLength, michael@0: NS_CSTRING_CONTAINER_INIT_DEPEND | michael@0: NS_CSTRING_CONTAINER_INIT_SUBSTRING); michael@0: } michael@0: michael@0: nsDependentCSubstring(const abstract_string_type& aStr, michael@0: uint32_t aStartPos); michael@0: nsDependentCSubstring(const abstract_string_type& aStr, michael@0: uint32_t aStartPos, uint32_t aLength); michael@0: michael@0: void Rebind(const char_type *aStart, uint32_t aLength) michael@0: { michael@0: NS_CStringContainerFinish(*this); michael@0: NS_CStringContainerInit2(*this, aStart, aLength, michael@0: NS_CSTRING_CONTAINER_INIT_DEPEND | michael@0: NS_CSTRING_CONTAINER_INIT_SUBSTRING); michael@0: } michael@0: michael@0: private: michael@0: self_type& operator=(const self_type& aString) MOZ_DELETE; michael@0: }; michael@0: michael@0: michael@0: /** michael@0: * Various nsDependentC?Substring constructor functions michael@0: */ michael@0: michael@0: // char16_t michael@0: inline const nsDependentSubstring michael@0: Substring( const nsAString& str, uint32_t startPos ) michael@0: { michael@0: return nsDependentSubstring(str, startPos); michael@0: } michael@0: michael@0: inline const nsDependentSubstring michael@0: Substring( const nsAString& str, uint32_t startPos, uint32_t length ) michael@0: { michael@0: return nsDependentSubstring(str, startPos, length); michael@0: } michael@0: michael@0: inline const nsDependentSubstring michael@0: Substring( const char16_t* start, const char16_t* end ) michael@0: { michael@0: NS_ABORT_IF_FALSE(uint32_t(end - start) == uintptr_t(end - start), "string too long"); michael@0: return nsDependentSubstring(start, uint32_t(end - start)); michael@0: } michael@0: michael@0: inline const nsDependentSubstring michael@0: Substring( const char16_t* start, uint32_t length ) michael@0: { michael@0: return nsDependentSubstring(start, length); michael@0: } michael@0: michael@0: inline const nsDependentSubstring michael@0: StringHead( const nsAString& str, uint32_t count ) michael@0: { michael@0: return nsDependentSubstring(str, 0, count); michael@0: } michael@0: michael@0: inline const nsDependentSubstring michael@0: StringTail( const nsAString& str, uint32_t count ) michael@0: { michael@0: return nsDependentSubstring(str, str.Length() - count, count); michael@0: } michael@0: michael@0: // char michael@0: inline const nsDependentCSubstring michael@0: Substring( const nsACString& str, uint32_t startPos ) michael@0: { michael@0: return nsDependentCSubstring(str, startPos); michael@0: } michael@0: michael@0: inline const nsDependentCSubstring michael@0: Substring( const nsACString& str, uint32_t startPos, uint32_t length ) michael@0: { michael@0: return nsDependentCSubstring(str, startPos, length); michael@0: } michael@0: michael@0: inline michael@0: const nsDependentCSubstring michael@0: Substring( const char* start, const char* end ) michael@0: { michael@0: NS_ABORT_IF_FALSE(uint32_t(end - start) == uintptr_t(end - start), "string too long"); michael@0: return nsDependentCSubstring(start, uint32_t(end - start)); michael@0: } michael@0: michael@0: inline michael@0: const nsDependentCSubstring michael@0: Substring( const char* start, uint32_t length ) michael@0: { michael@0: return nsDependentCSubstring(start, length); michael@0: } michael@0: michael@0: inline const nsDependentCSubstring michael@0: StringHead( const nsACString& str, uint32_t count ) michael@0: { michael@0: return nsDependentCSubstring(str, 0, count); michael@0: } michael@0: michael@0: inline const nsDependentCSubstring michael@0: StringTail( const nsACString& str, uint32_t count ) michael@0: { michael@0: return nsDependentCSubstring(str, str.Length() - count, count); michael@0: } michael@0: michael@0: michael@0: inline bool michael@0: StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring, michael@0: nsAString::ComparatorFunc aComparator = nsAString::DefaultComparator) michael@0: { michael@0: return aSubstring.Length() <= aSource.Length() && michael@0: StringHead(aSource, aSubstring.Length()).Equals(aSubstring, aComparator); michael@0: } michael@0: michael@0: inline bool michael@0: StringEndsWith(const nsAString& aSource, const nsAString& aSubstring, michael@0: nsAString::ComparatorFunc aComparator = nsAString::DefaultComparator) michael@0: { michael@0: return aSubstring.Length() <= aSource.Length() && michael@0: StringTail(aSource, aSubstring.Length()).Equals(aSubstring, aComparator); michael@0: } michael@0: michael@0: inline bool michael@0: StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring, michael@0: nsACString::ComparatorFunc aComparator = nsACString::DefaultComparator) michael@0: { michael@0: return aSubstring.Length() <= aSource.Length() && michael@0: StringHead(aSource, aSubstring.Length()).Equals(aSubstring, aComparator); michael@0: } michael@0: michael@0: inline bool michael@0: StringEndsWith(const nsACString& aSource, const nsACString& aSubstring, michael@0: nsACString::ComparatorFunc aComparator = nsACString::DefaultComparator) michael@0: { michael@0: return aSubstring.Length() <= aSource.Length() && michael@0: StringTail(aSource, aSubstring.Length()).Equals(aSubstring, aComparator); michael@0: } michael@0: michael@0: /** michael@0: * Trim whitespace from the beginning and end of a string; then compress michael@0: * remaining runs of whitespace characters to a single space. michael@0: */ michael@0: NS_HIDDEN_(void) michael@0: CompressWhitespace(nsAString& aString); michael@0: michael@0: #define EmptyCString() nsCString() michael@0: #define EmptyString() nsString() michael@0: michael@0: /** michael@0: * Convert an ASCII string to all upper/lowercase (a-z,A-Z only). As a bonus, michael@0: * returns the string length. michael@0: */ michael@0: NS_HIDDEN_(uint32_t) michael@0: ToLowerCase(nsACString& aStr); michael@0: michael@0: NS_HIDDEN_(uint32_t) michael@0: ToUpperCase(nsACString& aStr); michael@0: michael@0: NS_HIDDEN_(uint32_t) michael@0: ToLowerCase(const nsACString& aSrc, nsACString& aDest); michael@0: michael@0: NS_HIDDEN_(uint32_t) michael@0: ToUpperCase(const nsACString& aSrc, nsACString& aDest); michael@0: michael@0: /** michael@0: * The following declarations are *deprecated*, and are included here only michael@0: * to make porting from existing code that doesn't use the frozen string API michael@0: * easier. They may disappear in the future. michael@0: */ michael@0: michael@0: inline char* michael@0: ToNewCString(const nsACString& aStr) michael@0: { michael@0: return NS_CStringCloneData(aStr); michael@0: } michael@0: michael@0: inline char16_t* michael@0: ToNewUnicode(const nsAString& aStr) michael@0: { michael@0: return NS_StringCloneData(aStr); michael@0: } michael@0: michael@0: typedef nsString PromiseFlatString; michael@0: typedef nsCString PromiseFlatCString; michael@0: michael@0: typedef nsCString nsAutoCString; michael@0: typedef nsString nsAutoString; michael@0: michael@0: NS_HIDDEN_(bool) ParseString(const nsACString& aAstring, char aDelimiter, michael@0: nsTArray& aArray); michael@0: michael@0: #endif // nsStringAPI_h__