mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
bug 254740 : mailnews quick search is case sensitive with non-ASCII characters (r=neil, sr=bienvenu)
This commit is contained in:
parent
b15a475d7f
commit
76d4b71659
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user