Bug 1768418 - Move various methods from nsTString to nsTSubstring/nsTStringRepr. r=xpcom-reviewers,nika

No reason these don't work on substrings.

Remove StripChars since it has an existing nsTSubstring version. Make
callers use rightly-typed characters for those.

Differential Revision: https://phabricator.services.mozilla.com/D145864
This commit is contained in:
Emilio Cobos Álvarez 2022-05-13 15:39:19 +00:00
Родитель 702df2639c
Коммит 87ff5a5d8d
9 изменённых файлов: 370 добавлений и 446 удалений

Просмотреть файл

@ -171,7 +171,7 @@ nsresult HTMLFrameSetElement::ParseRowCol(const nsAString& aValue,
nsAutoString spec(aValue);
// remove whitespace (Bug 33699) and quotation marks (bug 224598)
// also remove leading/trailing commas (bug 31482)
spec.StripChars(" \n\r\t\"\'");
spec.StripChars(u" \n\r\t\"\'");
spec.Trim(",");
// Count the commas. Don't count more than X commas (bug 576447).

Просмотреть файл

@ -602,7 +602,7 @@ nsFind::Find(const nsAString& aPatText, nsRange* aSearchRange,
}
// Ignore soft hyphens in the pattern
static const char kShy[] = {char(CH_SHY), 0};
static const char16_t kShy[] = {CH_SHY, 0};
patAutoStr.StripChars(kShy);
const char16_t* patStr = patAutoStr.get();

Просмотреть файл

@ -1181,7 +1181,7 @@ bool nsLocalFile::CleanupCmdHandlerPath(nsAString& aCommandHandler) {
handlerCommand.Assign(destination.get());
// Remove quotes around paths
handlerCommand.StripChars("\"");
handlerCommand.StripChars(u"\"");
// Strip windows host process bootstrap so we can get to the actual
// handler.

Просмотреть файл

@ -778,65 +778,68 @@ static void RFind_ComputeSearchRange(uint32_t bigLen, uint32_t littleLen,
// specialized methods:
namespace mozilla::detail {
template <typename T>
template <typename Q, typename EnableIfChar16>
int32_t nsTString<T>::Find(const self_type& aString, int32_t aOffset,
int32_t aCount) const {
int32_t nsTStringRepr<T>::Find(const self_type& aString, int32_t aOffset,
int32_t aCount) const {
// this method changes the meaning of aOffset and aCount:
Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
// Capture the raw buffer locally to help msvc deduce the type.
const char_type* str = aString.get();
const char_type* str = aString.BeginReading();
int32_t result = FindSubstring(this->mData + aOffset, aCount, str,
aString.Length(), false);
if (result != kNotFound) result += aOffset;
return result;
}
template int32_t nsTString<char16_t>::Find(const self_type&, int32_t,
int32_t) const;
template int32_t nsTStringRepr<char16_t>::Find(const self_type&, int32_t,
int32_t) const;
template <typename T>
template <typename Q, typename EnableIfChar16>
int32_t nsTString<T>::Find(const char_type* aString, int32_t aOffset,
int32_t aCount) const {
int32_t nsTStringRepr<T>::Find(const char_type* aString, int32_t aOffset,
int32_t aCount) const {
return Find(nsTDependentString<T>(aString), aOffset, aCount);
}
template int32_t nsTString<char16_t>::Find(const char_type*, int32_t,
int32_t) const;
template int32_t nsTStringRepr<char16_t>::Find(const char_type*, int32_t,
int32_t) const;
template <typename T>
template <typename Q, typename EnableIfChar16>
int32_t nsTString<T>::RFind(const self_type& aString, int32_t aOffset,
int32_t aCount) const {
int32_t nsTStringRepr<T>::RFind(const self_type& aString, int32_t aOffset,
int32_t aCount) const {
// this method changes the meaning of aOffset and aCount:
RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
// Capture the raw buffer locally to help msvc deduce the type.
const char_type* str = aString.get();
const char_type* str = aString.BeginReading();
int32_t result = RFindSubstring(this->mData + aOffset, aCount, str,
aString.Length(), false);
if (result != kNotFound) result += aOffset;
return result;
}
template int32_t nsTString<char16_t>::RFind(const self_type&, int32_t,
int32_t) const;
template int32_t nsTStringRepr<char16_t>::RFind(const self_type&, int32_t,
int32_t) const;
template <typename T>
template <typename Q, typename EnableIfChar16>
int32_t nsTString<T>::RFind(const char_type* aString, int32_t aOffset,
int32_t aCount) const {
int32_t nsTStringRepr<T>::RFind(const char_type* aString, int32_t aOffset,
int32_t aCount) const {
return RFind(nsTDependentString<T>(aString), aOffset, aCount);
}
template int32_t nsTString<char16_t>::RFind(const char_type*, int32_t,
int32_t) const;
template int32_t nsTStringRepr<char16_t>::RFind(const char_type*, int32_t,
int32_t) const;
template <typename T>
template <typename Q, typename EnableIfChar16>
int32_t nsTString<T>::FindCharInSet(const char* aSet, int32_t aOffset) const {
int32_t nsTStringRepr<T>::FindCharInSet(const char* aSet,
int32_t aOffset) const {
if (aOffset < 0)
aOffset = 0;
else if (aOffset >= int32_t(this->mLength))
@ -848,11 +851,14 @@ int32_t nsTString<T>::FindCharInSet(const char* aSet, int32_t aOffset) const {
return result;
}
template int32_t nsTString<char16_t>::FindCharInSet(const char*, int32_t) const;
template int32_t nsTStringRepr<char16_t>::FindCharInSet(const char*,
int32_t) const;
} // namespace mozilla::detail
template <typename T>
template <typename Q, typename EnableIfChar16>
void nsTString<T>::ReplaceChar(const char* aSet, char16_t aNewChar) {
void nsTSubstring<T>::ReplaceChar(const char* aSet, char16_t aNewChar) {
if (!this->EnsureMutable()) // XXX do this lazily?
this->AllocFailed(this->mLength);
@ -869,8 +875,7 @@ void nsTString<T>::ReplaceChar(const char* aSet, char16_t aNewChar) {
}
}
namespace mozilla {
namespace detail {
namespace mozilla::detail {
template <typename T>
template <typename Q, typename EnableIfChar>
@ -927,27 +932,21 @@ bool nsTStringRepr<T>::EqualsIgnoreCase(const incompatible_char_type* aString,
template bool nsTStringRepr<char16_t>::EqualsIgnoreCase(
const incompatible_char_type*, size_type) const;
} // namespace detail
} // namespace mozilla
/**
* nsTString::ToDouble
*/
template <>
double nsTString<char>::ToDouble(TrailingCharsPolicy aTrailingCharsPolicy,
nsresult* aErrorCode) const {
double nsTStringRepr<char>::ToDouble(bool aAllowTrailingChars,
nsresult* aErrorCode) const {
double res = 0.0;
if (this->mLength > 0) {
char* conv_stopped;
const char* str = this->mData;
// Use PR_strtod, not strtod, since we don't want locale involved.
res = PR_strtod(str, &conv_stopped);
if (aTrailingCharsPolicy == TrailingCharsPolicy::Allow &&
conv_stopped != str) {
if (aAllowTrailingChars && conv_stopped != str) {
*aErrorCode = NS_OK;
} else if (aTrailingCharsPolicy == TrailingCharsPolicy::Disallow &&
conv_stopped == str + this->mLength) {
} else if (!aAllowTrailingChars && conv_stopped == str + this->mLength) {
*aErrorCode = NS_OK;
} else {
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
@ -960,36 +959,11 @@ double nsTString<char>::ToDouble(TrailingCharsPolicy aTrailingCharsPolicy,
}
template <>
double nsTString<char>::ToDouble(nsresult* aErrorCode) const {
return ToDouble(TrailingCharsPolicy::Disallow, aErrorCode);
double nsTStringRepr<char16_t>::ToDouble(bool aAllowTrailingChars,
nsresult* aErrorCode) const {
NS_LossyConvertUTF16toASCII cString(BeginReading(), Length());
return aAllowTrailingChars ? cString.ToDoubleAllowTrailingChars(aErrorCode)
: cString.ToDouble(aErrorCode);
}
template <>
double nsTString<char16_t>::ToDouble(nsresult* aErrorCode) const {
return NS_LossyConvertUTF16toASCII(*this).ToDouble(aErrorCode);
}
template <typename T>
float nsTString<T>::ToFloat(nsresult* aErrorCode) const {
return (float)ToDouble(aErrorCode);
}
template <>
double nsTString<char>::ToDoubleAllowTrailingChars(nsresult* aErrorCode) const {
return ToDouble(TrailingCharsPolicy::Allow, aErrorCode);
}
template <>
double nsTString<char16_t>::ToDoubleAllowTrailingChars(
nsresult* aErrorCode) const {
return NS_LossyConvertUTF16toASCII(*this).ToDoubleAllowTrailingChars(
aErrorCode);
}
template <typename T>
float nsTString<T>::ToFloatAllowTrailingChars(nsresult* aErrorCode) const {
return (float)ToDoubleAllowTrailingChars(aErrorCode);
}
template class nsTString<char>;
template class nsTString<char16_t>;
} // namespace mozilla::detail

Просмотреть файл

@ -27,6 +27,8 @@ class nsTString : public nsTSubstring<T> {
public:
typedef nsTString<T> self_type;
using repr_type = mozilla::detail::nsTStringRepr<T>;
#ifdef __clang__
// bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
using typename nsTSubstring<T>::substring_type;
@ -176,165 +178,14 @@ class nsTString : public nsTSubstring<T> {
char_type operator[](index_type aIndex) const { return CharAt(aIndex); }
/**
* 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 nsTString<char>& 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;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t Find(const self_type& aString, int32_t aOffset = 0,
int32_t aCount = -1) const;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t Find(const char_type* aString, int32_t aOffset = 0,
int32_t aCount = -1) const;
#ifdef MOZ_USE_CHAR16_WRAPPER
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
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
/**
* 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
*/
// Case aIgnoreCase option only with char versions
int32_t RFind(const nsTString<char>& 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;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t RFind(const self_type& aString, int32_t aOffset = -1,
int32_t aCount = -1) const;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t RFind(const char_type* aString, int32_t aOffset = -1,
int32_t aCount = -1) const;
/**
* 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_type* aString, int32_t aOffset = 0) const;
int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const {
return FindCharInSet(aString.get(), aOffset);
}
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const;
/**
* 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);
return repr_type::RFindCharInSet(aString.get(), aOffset);
}
/**
* 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;
/**
* Similar to above ToDouble and ToFloat but allows trailing characters that
* are not converted.
*/
double ToDoubleAllowTrailingChars(nsresult* aErrorCode) const;
float ToFloatAllowTrailingChars(nsresult* aErrorCode) const;
/**
* |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
* any _other_ way than they are now. Consider these alternatives
*
* // ...a member function that returns a |Substring|
* aWritable = aReadable.Left(17);
* // ...a global function that returns a |Substring|
* aWritable = Left(aReadable, 17);
* // ...a global function that does the assignment
* Left(aReadable, 17, aWritable);
*
* as opposed to the current signature
*
* // ...a member function that does the assignment
* aReadable.Left(aWritable, 17);
*
* 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, index_type aStartPos,
size_type 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(this->Length(), aCount);
return Mid(aResult, this->mLength - aCount, aCount);
using repr_type::RFindCharInSet;
int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const {
return repr_type::FindCharInSet(aString.get(), aOffset);
}
using repr_type::FindCharInSet;
/**
* Set a char inside this string at given index
@ -343,77 +194,8 @@ class nsTString : public nsTSubstring<T> {
* @param anIndex is the ofs where you want to write the given char
* @return TRUE if successful
*/
bool SetCharAt(char16_t aChar, index_type 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_type* aSet);
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
bool StripChars(const incompatible_char_type* aSet, const fallible_t&);
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
void StripChars(const incompatible_char_type* aSet);
/**
* 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_type* aSet, char_type aNewChar);
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
void ReplaceChar(const char* aSet, char16_t aNewChar);
/**
* 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);
[[nodiscard]] bool ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue,
const fallible_t&);
[[nodiscard]] 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);
/**
* Allow this string to be bound to a character buffer
* until the string is rebound or mutated; the caller
@ -447,26 +229,10 @@ class nsTString : public nsTSubstring<T> {
: substring_type(char_traits::sEmptyBuffer, 0,
aDataFlags | DataFlags::TERMINATED,
ClassFlags::NULL_TERMINATED) {}
enum class TrailingCharsPolicy {
Disallow,
Allow,
};
// Utility function for ToDouble and ToDoubleAllowTrailingChars.
double ToDouble(TrailingCharsPolicy aTrailingCharsPolicy,
nsresult* aErrorCode) const;
struct Segment {
uint32_t mBegin, mLength;
Segment(uint32_t aBegin, uint32_t aLength)
: mBegin(aBegin), mLength(aLength) {}
};
};
// TODO(erahm): Do something with ToDouble so that we can extern the
// nsTString templates.
// extern template class nsTString<char>;
// extern template class nsTString<char16_t>;
extern template class nsTString<char>;
extern template class nsTString<char16_t>;
/**
* nsTAutoStringN

Просмотреть файл

@ -8,71 +8,58 @@
#include "nsASCIIMask.h"
#include "mozilla/CheckedInt.h"
/**
* nsTString::Find
*
* aOffset specifies starting index
* aCount specifies number of string compares (iterations)
*/
namespace mozilla::detail {
template <typename T>
int32_t nsTString<T>::Find(const nsTString<char>& aString, bool aIgnoreCase,
int32_t aOffset, int32_t aCount) const {
int32_t nsTStringRepr<T>::Find(const nsTStringRepr<char>& aString,
bool aIgnoreCase, int32_t aOffset,
int32_t aCount) const {
// this method changes the meaning of aOffset and aCount:
Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
int32_t result = FindSubstring(this->mData + aOffset, aCount, aString.get(),
aString.Length(), aIgnoreCase);
int32_t result =
FindSubstring(this->mData + aOffset, aCount, aString.BeginReading(),
aString.Length(), aIgnoreCase);
if (result != kNotFound) result += aOffset;
return result;
}
template <typename T>
int32_t nsTString<T>::Find(const char* aString, bool aIgnoreCase,
int32_t aOffset, int32_t aCount) const {
int32_t nsTStringRepr<T>::Find(const char* aString, bool aIgnoreCase,
int32_t aOffset, int32_t aCount) const {
return Find(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
}
/**
* nsTString::RFind
*
* aOffset specifies starting index
* aCount specifies number of string compares (iterations)
*/
template <typename T>
int32_t nsTString<T>::RFind(const nsTString<char>& aString, bool aIgnoreCase,
int32_t aOffset, int32_t aCount) const {
int32_t nsTStringRepr<T>::RFind(const nsTStringRepr<char>& aString,
bool aIgnoreCase, int32_t aOffset,
int32_t aCount) const {
// this method changes the meaning of aOffset and aCount:
RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
int32_t result = RFindSubstring(this->mData + aOffset, aCount, aString.get(),
aString.Length(), aIgnoreCase);
int32_t result =
RFindSubstring(this->mData + aOffset, aCount, aString.BeginReading(),
aString.Length(), aIgnoreCase);
if (result != kNotFound) result += aOffset;
return result;
}
template <typename T>
int32_t nsTString<T>::RFind(const char* aString, bool aIgnoreCase,
int32_t aOffset, int32_t aCount) const {
int32_t nsTStringRepr<T>::RFind(const char* aString, bool aIgnoreCase,
int32_t aOffset, int32_t aCount) const {
return RFind(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
}
/**
* nsTString::RFindChar
*/
template <typename T>
int32_t nsTString<T>::RFindChar(char16_t aChar, int32_t aOffset,
int32_t aCount) const {
int32_t nsTStringRepr<T>::RFindChar(char16_t aChar, int32_t aOffset,
int32_t aCount) const {
return nsBufferRoutines<T>::rfind_char(this->mData, this->mLength, aOffset,
aChar, aCount);
}
/**
* nsTString::FindCharInSet
*/
template <typename T>
int32_t nsTString<T>::FindCharInSet(const char_type* aSet,
int32_t aOffset) const {
int32_t nsTStringRepr<T>::FindCharInSet(const char_type* aSet,
int32_t aOffset) const {
if (aOffset < 0)
aOffset = 0;
else if (aOffset >= int32_t(this->mLength))
@ -89,8 +76,8 @@ int32_t nsTString<T>::FindCharInSet(const char_type* aSet,
*/
template <typename T>
int32_t nsTString<T>::RFindCharInSet(const char_type* aSet,
int32_t aOffset) const {
int32_t nsTStringRepr<T>::RFindCharInSet(const char_type* aSet,
int32_t aOffset) const {
// We want to pass a "data length" to ::RFindCharInSet
if (aOffset < 0 || aOffset > int32_t(this->mLength))
aOffset = this->mLength;
@ -100,12 +87,13 @@ int32_t nsTString<T>::RFindCharInSet(const char_type* aSet,
return ::RFindCharInSet(this->mData, aOffset, aSet);
}
} // namespace mozilla::detail
/**
* nsTString::Mid
*/
template <typename T>
typename nsTString<T>::size_type nsTString<T>::Mid(
typename nsTSubstring<T>::size_type nsTSubstring<T>::Mid(
self_type& aResult, index_type aStartPos, size_type aLengthToCopy) const {
if (aStartPos == 0 && aLengthToCopy >= this->mLength)
aResult = *this;
@ -130,49 +118,18 @@ bool nsTString<T>::SetCharAt(char16_t aChar, index_type aIndex) {
}
/**
* nsTString::StripChars,StripChar,StripWhitespace
* nsTSubstring::StripWhitespace
*/
template <typename T>
template <typename Q, typename EnableIfChar16>
void nsTString<T>::StripChars(const incompatible_char_type* aSet) {
if (!StripChars(aSet, mozilla::fallible)) {
this->AllocFailed(this->mLength);
}
}
template void nsTString<char16_t>::StripChars(const incompatible_char_type*);
template <typename T>
template <typename Q, typename EnableIfChar16>
bool nsTString<T>::StripChars(const incompatible_char_type* aSet,
const fallible_t&) {
if (!this->EnsureMutable()) {
return false;
}
this->mLength =
nsBufferRoutines<T>::strip_chars(this->mData, this->mLength, aSet);
return true;
}
template bool nsTString<char16_t>::StripChars(const incompatible_char_type*,
const fallible_t&);
template <typename T>
void nsTString<T>::StripChars(const char_type* aSet) {
nsTSubstring<T>::StripChars(aSet);
}
template <typename T>
void nsTString<T>::StripWhitespace() {
void nsTSubstring<T>::StripWhitespace() {
if (!StripWhitespace(mozilla::fallible)) {
this->AllocFailed(this->mLength);
}
}
template <typename T>
bool nsTString<T>::StripWhitespace(const fallible_t&) {
bool nsTSubstring<T>::StripWhitespace(const fallible_t&) {
if (!this->EnsureMutable()) {
return false;
}
@ -182,11 +139,11 @@ bool nsTString<T>::StripWhitespace(const fallible_t&) {
}
/**
* nsTString::ReplaceChar,ReplaceSubstring
* nsTSubstring::ReplaceChar,ReplaceSubstring
*/
template <typename T>
void nsTString<T>::ReplaceChar(char_type aOldChar, char_type aNewChar) {
void nsTSubstring<T>::ReplaceChar(char_type aOldChar, char_type aNewChar) {
if (!this->EnsureMutable()) // XXX do this lazily?
this->AllocFailed(this->mLength);
@ -196,7 +153,7 @@ void nsTString<T>::ReplaceChar(char_type aOldChar, char_type aNewChar) {
}
template <typename T>
void nsTString<T>::ReplaceChar(const char_type* aSet, char_type aNewChar) {
void nsTSubstring<T>::ReplaceChar(const char_type* aSet, char_type aNewChar) {
if (!this->EnsureMutable()) // XXX do this lazily?
this->AllocFailed(this->mLength);
@ -213,28 +170,28 @@ void nsTString<T>::ReplaceChar(const char_type* aSet, char_type aNewChar) {
}
}
template void nsTString<char16_t>::ReplaceChar(const char*, char16_t);
template void nsTSubstring<char16_t>::ReplaceChar(const char*, char16_t);
void ReleaseData(void* aData, nsAString::DataFlags aFlags);
template <typename T>
void nsTString<T>::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue) {
void nsTSubstring<T>::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue) {
ReplaceSubstring(nsTDependentString<T>(aTarget),
nsTDependentString<T>(aNewValue));
}
template <typename T>
bool nsTString<T>::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue,
const fallible_t& aFallible) {
bool nsTSubstring<T>::ReplaceSubstring(const char_type* aTarget,
const char_type* aNewValue,
const fallible_t& aFallible) {
return ReplaceSubstring(nsTDependentString<T>(aTarget),
nsTDependentString<T>(aNewValue), aFallible);
}
template <typename T>
void nsTString<T>::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue) {
void nsTSubstring<T>::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue) {
if (!ReplaceSubstring(aTarget, aNewValue, mozilla::fallible)) {
// Note that this may wildly underestimate the allocation that failed, as
// we could have been replacing multiple copies of aTarget.
@ -243,9 +200,15 @@ void nsTString<T>::ReplaceSubstring(const self_type& aTarget,
}
template <typename T>
bool nsTString<T>::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue,
const fallible_t&) {
bool nsTSubstring<T>::ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue,
const fallible_t&) {
struct Segment {
uint32_t mBegin, mLength;
Segment(uint32_t aBegin, uint32_t aLength)
: mBegin(aBegin), mLength(aLength) {}
};
if (aTarget.Length() == 0) return true;
// Remember all of the non-matching parts.
@ -340,12 +303,12 @@ bool nsTString<T>::ReplaceSubstring(const self_type& aTarget,
}
/**
* nsTString::Trim
* nsTSubstring::Trim
*/
template <typename T>
void nsTString<T>::Trim(const char* aSet, bool aTrimLeading, bool aTrimTrailing,
bool aIgnoreQuotes) {
void nsTSubstring<T>::Trim(const char* aSet, bool aTrimLeading,
bool aTrimTrailing, bool aIgnoreQuotes) {
// the old implementation worried about aSet being null :-/
if (!aSet) return;
@ -397,11 +360,12 @@ void nsTString<T>::Trim(const char* aSet, bool aTrimLeading, bool aTrimTrailing,
}
/**
* nsTString::CompressWhitespace.
* nsTSubstring::CompressWhitespace.
*/
template <typename T>
void nsTString<T>::CompressWhitespace(bool aTrimLeading, bool aTrimTrailing) {
void nsTSubstring<T>::CompressWhitespace(bool aTrimLeading,
bool aTrimTrailing) {
// Quick exit
if (this->mLength == 0) {
return;

Просмотреть файл

@ -355,6 +355,132 @@ class nsTStringRepr {
reinterpret_cast<uintptr_t>(mData));
}
/**
* 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 nsTStringRepr<char>& 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;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t Find(const self_type& aString, int32_t aOffset = 0,
int32_t aCount = -1) const;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t Find(const char_type* aString, int32_t aOffset = 0,
int32_t aCount = -1) const;
#ifdef MOZ_USE_CHAR16_WRAPPER
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
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
/**
* 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
*/
// Case aIgnoreCase option only with char versions
int32_t RFind(const nsTStringRepr<char>& 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;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t RFind(const self_type& aString, int32_t aOffset = -1,
int32_t aCount = -1) const;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t RFind(const char_type* aString, int32_t aOffset = -1,
int32_t aCount = -1) const;
/**
* 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_type* aString, int32_t aOffset = 0) const;
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const;
/**
* 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;
/**
* 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 {
return ToDouble(/* aAllowTrailingChars = */ false, aErrorCode);
}
/**
* 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));
}
/**
* Similar to above ToDouble and ToFloat but allows trailing characters that
* are not converted.
*/
double ToDoubleAllowTrailingChars(nsresult* aErrorCode) const {
return ToDouble(/* aAllowTrailingChars = */ true, aErrorCode);
}
float ToFloatAllowTrailingChars(nsresult* aErrorCode) const {
return float(ToDoubleAllowTrailingChars(aErrorCode));
}
protected:
nsTStringRepr() = delete; // Never instantiate directly
@ -367,6 +493,8 @@ class nsTStringRepr {
static constexpr size_type kMaxCapacity = LengthStorage::kMax;
double ToDouble(bool aAllowTrailingChars, nsresult* aErrorCode) const;
/**
* Checks if the given capacity is valid for this string type.
*/
@ -380,6 +508,13 @@ class nsTStringRepr {
ClassFlags const mClassFlags;
};
template <>
double nsTStringRepr<char>::ToDouble(bool aAllowTrailingChars,
nsresult* aErrorCode) const;
template <>
double nsTStringRepr<char16_t>::ToDouble(bool aAllowTrailingChars,
nsresult* aErrorCode) const;
extern template class nsTStringRepr<char>;
extern template class nsTStringRepr<char16_t>;

Просмотреть файл

@ -550,6 +550,133 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
ReplaceLiteral(aCutStart, aCutLength, aStr, N - 1);
}
/**
* |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
* any _other_ way than they are now. Consider these alternatives
*
* // ...a member function that returns a |Substring|
* aWritable = aReadable.Left(17);
* // ...a global function that returns a |Substring|
* aWritable = Left(aReadable, 17);
* // ...a global function that does the assignment
* Left(aReadable, 17, aWritable);
*
* as opposed to the current signature
*
* // ...a member function that does the assignment
* aReadable.Left(aWritable, 17);
*
* 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, index_type aStartPos,
size_type 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(this->Length(), aCount);
return Mid(aResult, this->mLength - aCount, aCount);
}
/**
* This method strips whitespace throughout the string.
*/
void StripWhitespace();
bool StripWhitespace(const fallible_t&);
/**
* This method is used to remove all occurrences of aChar from this
* string.
*
* @param aChar -- char to be stripped
*/
void StripChar(char_type aChar);
/**
* This method is used to remove all occurrences of aChars from this
* string.
*
* @param aChars -- chars to be stripped
*/
void StripChars(const char_type* aChars);
/**
* This method is used to remove all occurrences of some characters this
* from this string. The characters removed have the corresponding
* entries in the bool array set to true; we retain all characters
* with code beyond 127.
* THE CALLER IS RESPONSIBLE for making sure the complete boolean
* array, 128 entries, is properly initialized.
*
* See also: ASCIIMask class.
*
* @param aToStrip -- Array where each entry is true if the
* corresponding ASCII character is to be stripped. All
* characters beyond code 127 are retained. Note that this
* parameter is of ASCIIMaskArray type, but we expand the typedef
* to avoid having to include nsASCIIMask.h in this include file
* as it brings other includes.
*/
void StripTaggedASCII(const std::array<bool, 128>& aToStrip);
/**
* A shortcut to strip \r and \n.
*/
void StripCRLF();
/**
* swaps occurence of 1 string for another
*/
void ReplaceChar(char_type aOldChar, char_type aNewChar);
void ReplaceChar(const char_type* aSet, char_type aNewChar);
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
void ReplaceChar(const char* aSet, char16_t aNewChar);
/**
* 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);
[[nodiscard]] bool ReplaceSubstring(const self_type& aTarget,
const self_type& aNewValue,
const fallible_t&);
[[nodiscard]] 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);
void Append(char_type aChar);
[[nodiscard]] bool Append(char_type aChar, const fallible_t& aFallible);
@ -1003,48 +1130,6 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
void NS_FASTCALL SetIsVoid(bool);
/**
* This method is used to remove all occurrences of aChar from this
* string.
*
* @param aChar -- char to be stripped
*/
void StripChar(char_type aChar);
/**
* This method is used to remove all occurrences of aChars from this
* string.
*
* @param aChars -- chars to be stripped
*/
void StripChars(const char_type* aChars);
/**
* This method is used to remove all occurrences of some characters this
* from this string. The characters removed have the corresponding
* entries in the bool array set to true; we retain all characters
* with code beyond 127.
* THE CALLER IS RESPONSIBLE for making sure the complete boolean
* array, 128 entries, is properly initialized.
*
* See also: ASCIIMask class.
*
* @param aToStrip -- Array where each entry is true if the
* corresponding ASCII character is to be stripped. All
* characters beyond code 127 are retained. Note that this
* parameter is of ASCIIMaskArray type, but we expand the typedef
* to avoid having to include nsASCIIMask.h in this include file
* as it brings other includes.
*/
void StripTaggedASCII(const std::array<bool, 128>& aToStrip);
/**
* A shortcut to strip \r and \n.
*/
void StripCRLF();
/**
* If the string uses a shared buffer, this method
* clears the pointer without releasing the buffer.

Просмотреть файл

@ -24,8 +24,8 @@ template class nsTSubstring<char16_t>;
template class nsTDependentSubstring<char>;
template class nsTDependentSubstring<char16_t>;
// Note: nsTString is skipped as it's implicitly instantiated by derived
// classes.
template class nsTString<char>;
template class nsTString<char16_t>;
template class nsTAutoStringN<char, 64>;
template class nsTAutoStringN<char16_t, 64>;