bug 254740 : mailnews quick search is case sensitive with non-ASCII characters (r=neil, sr=bienvenu)

This commit is contained in:
jshin%mailaps.org 2005-02-24 15:50:57 +00:00
parent b15a475d7f
commit 76d4b71659
3 changed files with 47 additions and 69 deletions

View File

@ -38,7 +38,6 @@
#include "nsString.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
#include "nsUnicharUtilCIID.h"
#include "nsICaseConversion.h"
#include "nsIServiceManager.h"
@ -263,13 +262,6 @@ ToUpperCase( const nsAString& aSource, nsAString& aDest )
copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter);
}
PRBool
CaseInsensitiveFindInReadable( const nsAString& aPattern, nsAString::const_iterator& aSearchStart, nsAString::const_iterator& aSearchEnd )
{
return FindInReadable(aPattern, aSearchStart, aSearchEnd, nsCaseInsensitiveStringComparator());
}
int
nsCaseInsensitiveStringComparator::operator()( const PRUnichar* lhs, const PRUnichar* rhs, PRUint32 aLength ) const
{

View File

@ -41,6 +41,7 @@
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#include "nsReadableUtils.h"
void ToLowerCase( nsAString& );
void ToUpperCase( nsAString& );
@ -54,8 +55,6 @@ void ToUpperCase( nsString& );
void ToLowerCase( const nsAString& aSource, nsAString& aDest );
void ToUpperCase( const nsAString& aSource, nsAString& aDest );
PRBool CaseInsensitiveFindInReadable( const nsAString& aPattern, nsAString::const_iterator&, nsAString::const_iterator& );
class nsCaseInsensitiveStringComparator
: public nsStringComparator
{
@ -64,6 +63,21 @@ class nsCaseInsensitiveStringComparator
virtual int operator()( PRUnichar, PRUnichar ) const;
};
inline PRBool CaseInsensitiveFindInReadable( const nsAString& aPattern,
nsAString::const_iterator& aSearchStart,
nsAString::const_iterator& aSearchEnd ) {
return FindInReadable(aPattern, aSearchStart, aSearchEnd,
nsCaseInsensitiveStringComparator());
}
inline PRBool CaseInsensitiveFindInReadable( const nsAString& aPattern,
const nsAString& aHay ) {
nsAString::const_iterator searchBegin, searchEnd;
return FindInReadable(aPattern,
aHay.BeginReading(searchBegin),
aHay.EndReading(searchEnd),
nsCaseInsensitiveStringComparator());
}
PRUnichar ToUpperCase(PRUnichar);
PRUnichar ToLowerCase(PRUnichar);

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Seth Spitzer <sspitzer@netscape.com>
* Jungshik Shin <jshin@mailaps.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -65,6 +66,7 @@
#include "nsISupportsObsolete.h"
#include "nsNetCID.h"
#include "nsIFileStreams.h"
#include "nsUnicharUtils.h"
//---------------------------------------------------------------------------
// nsMsgSearchTerm specifies one criterion, e.g. name contains phil
//---------------------------------------------------------------------------
@ -935,95 +937,65 @@ nsresult nsMsgSearchTerm::MatchString (const char *stringToMatch,
PRBool result = PR_FALSE;
nsresult err = NS_OK;
nsCAutoString n_str;
const char *utf8 = stringToMatch;
if(nsMsgSearchOp::IsEmpty != m_operator) // Save some performance for opIsEmpty
nsAutoString utf16StrToMatch;
nsAutoString needle;
// Save some performance for opIsEmpty
if(nsMsgSearchOp::IsEmpty != m_operator)
{
n_str = m_value.string;
NS_ASSERTION(IsUTF8(nsDependentCString(m_value.string)),
"m_value.string is not UTF-8");
CopyUTF8toUTF16(m_value.string, needle);
if (charset != nsnull)
{
nsAutoString out;
ConvertToUnicode(charset, stringToMatch ? stringToMatch : "", out);
utf8 = ToNewUTF8String(out);
ConvertToUnicode(charset, stringToMatch ? stringToMatch : "",
utf16StrToMatch);
}
else {
NS_ASSERTION(IsUTF8(nsDependentCString(stringToMatch)),
"stringToMatch is not UTF-8");
CopyUTF8toUTF16(stringToMatch, utf16StrToMatch);
}
}
switch (m_operator)
{
case nsMsgSearchOp::Contains:
if ((nsnull != utf8) && ((n_str.get())[0]) && /* INTL_StrContains(csid, n_header, n_str) */
PL_strcasestr(utf8, n_str.get()))
if (CaseInsensitiveFindInReadable(needle, utf16StrToMatch))
result = PR_TRUE;
break;
case nsMsgSearchOp::DoesntContain:
if ((nsnull != utf8) && ((n_str.get())[0]) && /* !INTL_StrContains(csid, n_header, n_str) */
!PL_strcasestr(utf8, n_str.get()))
if(!CaseInsensitiveFindInReadable(needle, utf16StrToMatch))
result = PR_TRUE;
break;
case nsMsgSearchOp::Is:
if(utf8)
{
if ((n_str.get())[0])
{
if (n_str.EqualsIgnoreCase(utf8) /* INTL_StrIs(csid, n_header, n_str)*/ )
result = PR_TRUE;
}
else if (utf8[0] == '\0') // Special case for "is <the empty string>"
result = PR_TRUE;
}
if(needle.Equals(utf16StrToMatch, nsCaseInsensitiveStringComparator()))
result = PR_TRUE;
break;
case nsMsgSearchOp::Isnt:
if(utf8)
{
if ((n_str.get())[0])
{
if (!n_str.EqualsIgnoreCase(utf8)/* INTL_StrIs(csid, n_header, n_str)*/ )
result = PR_TRUE;
}
else if (utf8[0] != '\0') // Special case for "isn't <the empty string>"
result = PR_TRUE;
}
if(!needle.Equals(utf16StrToMatch, nsCaseInsensitiveStringComparator()))
result = PR_TRUE;
break;
case nsMsgSearchOp::IsEmpty:
if (!PL_strlen(utf8))
// For IsEmpty, we didn't copy stringToMatch to utf16StrToMatch.
if (!PL_strlen(stringToMatch))
result = PR_TRUE;
break;
case nsMsgSearchOp::BeginsWith:
#ifdef DO_I18N_YET
if((nsnull != n_str) && (nsnull != utf8) && INTL_StrBeginWith(csid, utf8, n_str))
if (StringBeginsWith(utf16StrToMatch, needle,
nsCaseInsensitiveStringComparator()))
result = PR_TRUE;
#else
// ### DMB - not the most efficient way to do this.
if (PL_strncmp(utf8, n_str.get(), n_str.Length()) == 0)
result = PR_TRUE;
#endif
break;
case nsMsgSearchOp::EndsWith:
{
PRUint32 searchStrLen = (PRUint32) PL_strlen(utf8);
if (n_str.Length() <= searchStrLen)
{
PRInt32 sourceStrOffset = searchStrLen - n_str.Length();
if (PL_strcmp(utf8 + sourceStrOffset, n_str.get()) == 0)
result = PR_TRUE;
}
}
#ifdef DO_I18N_YET
{
if((nsnull != n_str) && (nsnull != utf8) && INTL_StrEndWith(csid, utf8, n_str))
result = PR_TRUE;
}
#else
#endif
if (StringEndsWith(utf16StrToMatch, needle,
nsCaseInsensitiveStringComparator()))
result = PR_TRUE;
break;
default:
NS_ASSERTION(PR_FALSE, "invalid operator matching search results");
}
if (utf8 != nsnull && utf8 != stringToMatch)
free((void *)utf8);
*pResult = result;
return err;
}