Bug 226439. Add ASCII and Literal versions of Append, EqualsIgnoreCase, and Assign. r+sr=darin

This commit is contained in:
roc+%cs.cmu.edu 2004-06-06 02:17:00 +00:00
Родитель 68357dc35c
Коммит a05b357612
5 изменённых файлов: 401 добавлений и 0 удалений

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

@ -155,6 +155,17 @@ struct nsCharTraits<PRUnichar>
return NS_STATIC_CAST(char_type*, memcpy(s1, s2, n * sizeof(char_type)));
}
static
char_type*
copyASCII( char_type* s1, const char* s2, size_t n )
{
for (char_type* s = s1; n--; ++s, ++s2) {
NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
*s = *s2;
}
return s1;
}
static
char_type*
assign( char_type* s, size_t n, char_type c )
@ -222,6 +233,58 @@ struct nsCharTraits<PRUnichar>
return 0;
}
/**
* Convert c to its lower-case form, but only if c is ASCII.
*/
static
char_type
ASCIIToLower( char_type c )
{
return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
}
static
int
compareLowerCaseToASCII( const char_type* s1, const char* s2, size_t n )
{
for ( ; n--; ++s1, ++s2 )
{
NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
"Unexpected uppercase character");
char_type lower_s1 = ASCIIToLower(*s1);
if ( lower_s1 != to_char_type(*s2) )
return to_int_type(lower_s1) - to_int_type(*s2);
}
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
compareLowerCaseToASCIINullTerminated( 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");
NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
"Unexpected uppercase character");
char_type lower_s1 = ASCIIToLower(*s1);
if ( lower_s1 != to_char_type(*s2) )
return to_int_type(lower_s1) - to_int_type(*s2);
}
if ( *s2 )
return -1;
return 0;
}
static
size_t
length( const char_type* s )
@ -359,6 +422,13 @@ struct nsCharTraits<char>
return NS_STATIC_CAST(char_type*, memcpy(s1, s2, n * sizeof(char_type)));
}
static
char_type*
copyASCII( char_type* s1, const char* s2, size_t n )
{
return copy(s1, s2, n);
}
static
char_type*
assign( char_type* s, size_t n, char_type c )
@ -410,6 +480,57 @@ struct nsCharTraits<char>
return 0;
}
/**
* Convert c to its lower-case form, but only if c is ASCII.
*/
static
char_type
ASCIIToLower( char_type c )
{
return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
}
static
int
compareLowerCaseToASCII( const char_type* s1, const char* s2, size_t n )
{
for ( ; n--; ++s1, ++s2 )
{
NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
"Unexpected uppercase character");
char_type lower_s1 = ASCIIToLower(*s1);
if ( lower_s1 != *s2 )
return to_int_type(lower_s1) - to_int_type(*s2);
}
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
compareLowerCaseToASCIINullTerminated( 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");
NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
"Unexpected uppercase character");
char_type lower_s1 = ASCIIToLower(*s1);
if ( lower_s1 != *s2 )
return to_int_type(lower_s1) - to_int_type(*s2);
}
if ( *s2 )
return -1;
return 0;
}
static
size_t
length( const char_type* s )

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

@ -234,6 +234,37 @@ class nsTAString_CharT
}
#endif
// The LowerCaseEquals methods compare the lower case version of
// this string to some ASCII/Literal string. The ASCII string is
// *not* lowercased for you. If you compare to an ASCII or literal
// string that contains an uppercase character, it is guaranteed to
// return false. We will throw assertions too.
NS_COM PRBool LowerCaseEqualsASCII( const char* data, size_type len ) const;
NS_COM PRBool LowerCaseEqualsASCII( const char* data ) const;
// LowerCaseEqualsLiteral 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. Use
// LowerCaseEqualsASCII for them.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
inline PRBool LowerCaseEqualsLiteral( const char* str ) const
{
return LowerCaseEqualsASCII(str);
}
#else
template<int N>
inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
{
return LowerCaseEqualsASCII(str, N-1);
}
template<int N>
inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
{
const char* s = str;
return LowerCaseEqualsASCII(s, N-1);
}
#endif
/**
* A string always references a non-null data pointer. In some
* applications (e.g., the DOM) it is necessary for a string class
@ -332,6 +363,24 @@ class nsTAString_CharT
NS_COM void Assign( const char_type* data, size_type length );
NS_COM void Assign( char_type c );
NS_COM void AssignASCII( const char* data, size_type length );
NS_COM void AssignASCII( const char* data );
// AssignLiteral 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. Use AssignASCII for those.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
void AssignLiteral( const char* str )
{ return AssignASCII(str); }
#else
template<int N>
void AssignLiteral( const char (&str)[N] )
{ return AssignASCII(str, N-1); }
template<int N>
void AssignLiteral( char (&str)[N] )
{ return AssignASCII(str, N-1); }
#endif
// copy-assignment operator. I must define my own if I don't want the compiler to make me one
self_type& operator=( const self_type& readable ) { Assign(readable); return *this; }
self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
@ -350,6 +399,24 @@ class nsTAString_CharT
NS_COM void Append( const char_type* data, size_type length );
NS_COM void Append( char_type c );
NS_COM void AppendASCII( const char* data, size_type length );
NS_COM void AppendASCII( const char* data );
// AppendLiteral 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. Use AppendASCII for those.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
void AppendLiteral( const char* str )
{ return AppendASCII(str); }
#else
template<int N>
void AppendLiteral( const char (&str)[N] )
{ return AppendASCII(str, N-1); }
template<int N>
void AppendLiteral( char (&str)[N] )
{ return AppendASCII(str, N-1); }
#endif
self_type& operator+=( const self_type& readable ) { Append(readable); return *this; }
self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; }
self_type& operator+=( const char_type* data ) { Append(data); return *this; }

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

@ -252,6 +252,37 @@ class nsTSubstring_CharT : public nsTAString_CharT
}
#endif
// The LowerCaseEquals methods compare the lower case version of
// this string to some ASCII/Literal string. The ASCII string is
// *not* lowercased for you. If you compare to an ASCII or literal
// string that contains an uppercase character, it is guaranteed to
// return false. We will throw assertions too.
NS_COM PRBool LowerCaseEqualsASCII( const char* data, size_type len ) const;
NS_COM PRBool LowerCaseEqualsASCII( const char* data ) const;
// LowerCaseEqualsLiteral 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. Use
// LowerCaseEqualsASCII for them.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
inline PRBool LowerCaseEqualsLiteral( const char* str ) const
{
return LowerCaseEqualsASCII(str);
}
#else
template<int N>
inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
{
return LowerCaseEqualsASCII(str, N-1);
}
template<int N>
inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
{
const char* s = str;
return LowerCaseEqualsASCII(s, N-1);
}
#endif
/**
* assignment
*/
@ -262,6 +293,24 @@ class nsTSubstring_CharT : public nsTAString_CharT
NS_COM void Assign( const substring_tuple_type& );
NS_COM void Assign( const abstract_string_type& );
NS_COM void AssignASCII( const char* data, size_type length );
NS_COM void AssignASCII( const char* data );
// AssignLiteral 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. Use AssignASCII for those.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
void AssignLiteral( const char* str )
{ return AssignASCII(str); }
#else
template<int N>
void AssignLiteral( const char (&str)[N] )
{ return AssignASCII(str, N-1); }
template<int N>
void AssignLiteral( char (&str)[N] )
{ return AssignASCII(str, N-1); }
#endif
self_type& operator=( char_type c ) { Assign(c); return *this; }
self_type& operator=( const char_type* data ) { Assign(data); return *this; }
self_type& operator=( const self_type& str ) { Assign(str); return *this; }
@ -281,12 +330,31 @@ class nsTSubstring_CharT : public nsTAString_CharT
NS_COM void Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
NS_COM void Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable );
NS_COM void ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
void Append( char_type c ) { Replace(mLength, 0, c); }
void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
void Append( const self_type& str ) { Replace(mLength, 0, str); }
void Append( const substring_tuple_type& tuple ) { Replace(mLength, 0, tuple); }
void Append( const abstract_string_type& readable ) { Replace(mLength, 0, readable); }
void AppendASCII( const char* data, size_type length = size_type(-1) ) { ReplaceASCII(mLength, 0, data, length); }
// AppendLiteral 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. Use AppendASCII for those.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
void AppendLiteral( const char* str )
{ return AppendASCII(str); }
#else
template<int N>
void AppendLiteral( const char (&str)[N] )
{ return AppendASCII(str, N-1); }
template<int N>
void AppendLiteral( char (&str)[N] )
{ return AppendASCII(str, N-1); }
#endif
self_type& operator+=( char_type c ) { Append(c); return *this; }
self_type& operator+=( const char_type* data ) { Append(data); return *this; }
self_type& operator+=( const self_type& str ) { Append(str); return *this; }

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

@ -123,6 +123,24 @@ nsTAString_CharT::EqualsASCII( const char* data ) const
return ToSubstring().EqualsASCII(data);
}
PRBool
nsTAString_CharT::LowerCaseEqualsASCII( const char* data, size_type len ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsSubstring()->LowerCaseEqualsASCII(data, len);
return ToSubstring().LowerCaseEqualsASCII(data, len);
}
PRBool
nsTAString_CharT::LowerCaseEqualsASCII( const char* data ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsSubstring()->LowerCaseEqualsASCII(data);
return ToSubstring().LowerCaseEqualsASCII(data);
}
PRBool
nsTAString_CharT::IsVoid() const
{
@ -244,6 +262,40 @@ nsTAString_CharT::Assign( const char_type* data, size_type length )
AsObsoleteString()->do_AssignFromElementPtrLength(data, length);
}
void
nsTAString_CharT::AssignASCII( const char* data )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsSubstring()->AssignASCII(data);
else
{
#ifdef CharT_is_char
AsObsoleteString()->do_AssignFromElementPtr(data);
#else
nsTAutoString_CharT temp;
temp.AssignASCII(data);
AsObsoleteString()->do_AssignFromReadable(temp);
#endif
}
}
void
nsTAString_CharT::AssignASCII( const char* data, size_type length )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsSubstring()->AssignASCII(data, length);
else
{
#ifdef CharT_is_char
AsObsoleteString()->do_AssignFromElementPtrLength(data, length);
#else
nsTAutoString_CharT temp;
temp.AssignASCII(data, length);
AsObsoleteString()->do_AssignFromReadable(temp);
#endif
}
}
void
nsTAString_CharT::Assign( char_type c )
{
@ -291,6 +343,40 @@ nsTAString_CharT::Append( const char_type* data, size_type length )
AsObsoleteString()->do_AppendFromElementPtrLength(data, length);
}
void
nsTAString_CharT::AppendASCII( const char* data )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsSubstring()->AppendASCII(data);
else
{
#ifdef CharT_is_char
AsObsoleteString()->do_AppendFromElementPtr(data);
#else
nsTAutoString_CharT temp;
temp.AssignASCII(data);
AsObsoleteString()->do_AppendFromReadable(temp);
#endif
}
}
void
nsTAString_CharT::AppendASCII( const char* data, size_type length )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsSubstring()->AppendASCII(data, length);
else
{
#ifdef CharT_is_char
AsObsoleteString()->do_AppendFromElementPtrLength(data, length);
#else
nsTAutoString_CharT temp;
temp.AssignASCII(data, length);
AsObsoleteString()->do_AppendFromReadable(temp);
#endif
}
}
void
nsTAString_CharT::Append( char_type c )
{

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

@ -292,6 +292,30 @@ nsTSubstring_CharT::Assign( const char_type* data, size_type length )
char_traits::copy(mData, data, length);
}
void
nsTSubstring_CharT::AssignASCII( const char* data, size_type length )
{
// A Unicode string can't depend on an ASCII string buffer,
// so this dependence check only applies to CStrings.
#ifdef CharT_is_char
if (IsDependentOn(data, data + length))
{
// take advantage of sharing here...
Assign(string_type(data, length));
return;
}
#endif
ReplacePrep(0, mLength, length);
char_traits::copyASCII(mData, data, length);
}
void
nsTSubstring_CharT::AssignASCII( const char* data )
{
AssignASCII(data, strlen(data));
}
void
nsTSubstring_CharT::Assign( const self_type& str )
{
@ -408,6 +432,29 @@ nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const cha
char_traits::copy(mData + cutStart, data, length);
}
void
nsTSubstring_CharT::ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length )
{
if (length == size_type(-1))
length = strlen(data);
// A Unicode string can't depend on an ASCII string buffer,
// so this dependence check only applies to CStrings.
#ifdef CharT_is_char
if (IsDependentOn(data, data + length))
{
nsTAutoString_CharT temp(data, length);
Replace(cutStart, cutLength, temp);
return;
}
#endif
ReplacePrep(cutStart, cutLength, length);
if (length > 0)
char_traits::copyASCII(mData + cutStart, data, length);
}
void
nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple )
{
@ -567,6 +614,18 @@ nsTSubstring_CharT::EqualsASCII( const char* data ) const
return char_traits::compareASCIINullTerminated(mData, mLength, data) == 0;
}
PRBool
nsTSubstring_CharT::LowerCaseEqualsASCII( const char* data, size_type len ) const
{
return mLength == len && char_traits::compareLowerCaseToASCII(mData, data, len) == 0;
}
PRBool
nsTSubstring_CharT::LowerCaseEqualsASCII( const char* data ) const
{
return char_traits::compareLowerCaseToASCIINullTerminated(mData, mLength, data) == 0;
}
nsTSubstring_CharT::size_type
nsTSubstring_CharT::CountChar( char_type c ) const
{