diff --git a/mozilla/xpcom/string/public/nsCharTraits.h b/mozilla/xpcom/string/public/nsCharTraits.h index 00f05d19df8..57384405bcb 100644 --- a/mozilla/xpcom/string/public/nsCharTraits.h +++ b/mozilla/xpcom/string/public/nsCharTraits.h @@ -200,6 +200,28 @@ struct nsCharTraits return 0; } + // this version assumes that s2 is null-terminated and s1 has length n. + // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, + // we return 1. + static + int + compareASCIINullTerminated( const char_type* s1, size_t n, const char* s2 ) + { + for ( ; n--; ++s1, ++s2 ) + { + if ( !*s2 ) + return 1; + NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character"); + if ( !eq_int_type(to_int_type(*s1), to_int_type(*s2)) ) + return to_int_type(*s1) - to_int_type(*s2); + } + + if ( *s2 ) + return -1; + + return 0; + } + static size_t length( const char_type* s ) @@ -364,6 +386,30 @@ struct nsCharTraits return compare(s1, s2, n); } + // this version assumes that s2 is null-terminated and s1 has length n. + // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, + // we return 1. + static + int + compareASCIINullTerminated( const char_type* s1, size_t n, const char* s2 ) + { + // can't use strcmp here because we don't want to stop when s1 + // contains a null + for ( ; n--; ++s1, ++s2 ) + { + if ( !*s2 ) + return 1; + NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character"); + if ( *s1 != *s2 ) + return to_int_type(*s1) - to_int_type(*s2); + } + + if ( *s2 ) + return -1; + + return 0; + } + static size_t length( const char_type* s ) diff --git a/mozilla/xpcom/string/public/nsTAString.h b/mozilla/xpcom/string/public/nsTAString.h index 8eb4fcf3a12..a95d61ccbe3 100644 --- a/mozilla/xpcom/string/public/nsTAString.h +++ b/mozilla/xpcom/string/public/nsTAString.h @@ -198,10 +198,18 @@ class nsTAString_CharT NS_COM PRBool Equals( const char_type*, const comparator_type& ) const; /** - * An efficient comparison with ASCII that can be used even for - * wide strings. + * An efficient comparison with ASCII that can be used even + * for wide strings. Call this version when you know the + * length of 'data'. */ NS_COM PRBool EqualsASCII( const char* data, size_type len ) const; + /** + * An efficient comparison with ASCII that can be used even + * for wide strings. Call this version when 'data' is + * null-terminated. + */ + NS_COM PRBool EqualsASCII( const char* data ) const; + // EqualsLiteral must ONLY be applied to an actual literal string. // Do not attempt to use it with a regular char* pointer, or with a char // array variable. @@ -210,7 +218,7 @@ class nsTAString_CharT #ifdef NS_DISABLE_LITERAL_TEMPLATE inline PRBool EqualsLiteral( const char* str ) const { - return EqualsASCII(str, strlen(str)); + return EqualsASCII(str); } #else template diff --git a/mozilla/xpcom/string/public/nsTSubstring.h b/mozilla/xpcom/string/public/nsTSubstring.h index a62311bafdd..35727c43f46 100644 --- a/mozilla/xpcom/string/public/nsTSubstring.h +++ b/mozilla/xpcom/string/public/nsTSubstring.h @@ -215,7 +215,19 @@ class nsTSubstring_CharT : public nsTAString_CharT NS_COM PRBool Equals( const char_type* data ) const; NS_COM PRBool Equals( const char_type* data, const comparator_type& comp ) const; + /** + * An efficient comparison with ASCII that can be used even + * for wide strings. Call this version when you know the + * length of 'data'. + */ NS_COM PRBool EqualsASCII( const char* data, size_type len ) const; + /** + * An efficient comparison with ASCII that can be used even + * for wide strings. Call this version when 'data' is + * null-terminated. + */ + NS_COM PRBool EqualsASCII( const char* data ) const; + // EqualsLiteral must ONLY be applied to an actual literal string. // Do not attempt to use it with a regular char* pointer, or with a char // array variable. @@ -224,7 +236,7 @@ class nsTSubstring_CharT : public nsTAString_CharT #ifdef NS_DISABLE_LITERAL_TEMPLATE inline PRBool EqualsLiteral( const char* str ) const { - return EqualsASCII(str, strlen(str)); + return EqualsASCII(str); } #else template diff --git a/mozilla/xpcom/string/src/nsTAString.cpp b/mozilla/xpcom/string/src/nsTAString.cpp index bd0aa3c0bf4..19efa706cf8 100644 --- a/mozilla/xpcom/string/src/nsTAString.cpp +++ b/mozilla/xpcom/string/src/nsTAString.cpp @@ -114,6 +114,15 @@ nsTAString_CharT::EqualsASCII( const char* data, size_type len ) const return ToSubstring().EqualsASCII(data, len); } +PRBool +nsTAString_CharT::EqualsASCII( const char* data ) const + { + if (mVTable == obsolete_string_type::sCanonicalVTable) + return AsSubstring()->EqualsASCII(data); + + return ToSubstring().EqualsASCII(data); + } + PRBool nsTAString_CharT::IsVoid() const { diff --git a/mozilla/xpcom/string/src/nsTSubstring.cpp b/mozilla/xpcom/string/src/nsTSubstring.cpp index d457959290f..91bd5cd0e36 100644 --- a/mozilla/xpcom/string/src/nsTSubstring.cpp +++ b/mozilla/xpcom/string/src/nsTSubstring.cpp @@ -561,6 +561,12 @@ nsTSubstring_CharT::EqualsASCII( const char* data, size_type len ) const return mLength == len && char_traits::compareASCII(mData, data, len) == 0; } +PRBool +nsTSubstring_CharT::EqualsASCII( const char* data ) const + { + return char_traits::compareASCIINullTerminated(mData, mLength, data) == 0; + } + nsTSubstring_CharT::size_type nsTSubstring_CharT::CountChar( char_type c ) const {