fix for 40346 - make the search term value PRUnichar* to make it i18n friendly

r=bienvenu
This commit is contained in:
alecf%netscape.com 2000-06-06 23:19:32 +00:00
parent c1551a0116
commit 396e8e21e0
10 changed files with 121 additions and 112 deletions

View File

@ -32,7 +32,7 @@ interface nsIMsgSearchValue : nsISupports {
// accessing these will throw an exception if the above
// attribute does not match the type!
attribute string str;
attribute wstring str;
attribute nsMsgPriorityValue priority;
attribute PRTime date;
attribute unsigned long status; // see MSG_FLAG in msgcom.h

View File

@ -23,11 +23,7 @@
#include "MailNewsTypes2.idl"
#include "nsIMsgFolder.idl"
interface nsIMsgHeaderParser;
%{C++
#include "nsIMsgHeaderParser.h"
%}
#include "nsIMsgHeaderParser.idl"
interface nsIMsgDatabase;
interface nsIMsgDBHdr;
@ -219,14 +215,3 @@ class nsMsgDIRServer;
[ptr] native nsSearchMenuItem(nsSearchMenuItem);
%{C++
/* Use this to help build menus in the search dialog. See APIs below */
#define kMsgSearchMenuLength 64
typedef struct nsMsgSearchMenuItem
{
int16 attrib;
char name[kMsgSearchMenuLength];
PRBool isEnabled;
} nsMsgSearchMenuItem;
%}

View File

@ -50,12 +50,8 @@ nsMsgFilterDataSource::nsMsgFilterDataSource()
{
NS_INIT_ISUPPORTS();
if (mGlobalRefCount == 0)
if (mGlobalRefCount++ == 0)
initGlobalObjects(getRDFService());
mGlobalRefCount++;
/* member initializers and constructor code */
}
nsMsgFilterDataSource::~nsMsgFilterDataSource()

View File

@ -52,7 +52,7 @@ nsresult nsMsgSearchOnlineMail::ValidateTerms ()
GetSearchCharsets(srcCharset, dstCharset);
// do IMAP specific validation
err = Encode (&m_encoding, m_searchTerms, srcCharset.GetUnicode(), dstCharset.GetUnicode());
err = Encode (m_encoding, m_searchTerms, dstCharset.GetUnicode());
NS_ASSERTION(NS_SUCCEEDED(err), "failed to encode imap search");
}
@ -239,9 +239,11 @@ nsresult nsMsgSearchOnlineMail::Search (PRBool *aDone)
}
nsresult nsMsgSearchOnlineMail::Encode (nsCString *pEncoding, nsISupportsArray *searchTerms, const PRUnichar *srcCharset, const PRUnichar *destCharset)
nsresult nsMsgSearchOnlineMail::Encode (nsCString& pEncoding,
nsISupportsArray *searchTerms,
const PRUnichar *destCharset)
{
char *imapTerms = nsnull;
nsXPIDLCString imapTerms;
//check if searchTerms are ascii only
PRBool asciiOnly = PR_TRUE;
@ -263,7 +265,7 @@ nsresult nsMsgSearchOnlineMail::Encode (nsCString *pEncoding, nsISupportsArray *
pTerm->GetAttrib(&attribute);
if (IsStringAttribute(attribute))
{
char *pchar;
PRUnichar *pchar;
nsCOMPtr <nsIMsgSearchValue> searchValue;
nsresult rv = pTerm->GetValue(getter_AddRefs(searchValue));
@ -276,7 +278,7 @@ nsresult nsMsgSearchOnlineMail::Encode (nsCString *pEncoding, nsISupportsArray *
continue;
for (; *pchar ; pchar++)
{
if (*pchar & 0x80)
if (*pchar & 0xFF80)
{
asciiOnly = PR_FALSE;
break;
@ -293,13 +295,13 @@ nsresult nsMsgSearchOnlineMail::Encode (nsCString *pEncoding, nsISupportsArray *
// Get the optional CHARSET parameter, in case we need it.
char *csname = GetImapCharsetParam(asciiOnly ? usAsciiCharSet.GetUnicode() : destCharset);
nsresult err = nsMsgSearchAdapter::EncodeImap (&imapTerms, searchTerms, srcCharset, asciiOnly ? usAsciiCharSet.GetUnicode(): destCharset, PR_FALSE);
nsresult err = nsMsgSearchAdapter::EncodeImap (getter_Copies(imapTerms), searchTerms, asciiOnly ? usAsciiCharSet.GetUnicode(): destCharset, PR_FALSE);
if (NS_SUCCEEDED(err))
{
pEncoding->Append("SEARCH");
pEncoding.Append("SEARCH");
if (csname)
pEncoding->Append(csname);
pEncoding->Append(imapTerms);
pEncoding.Append(csname);
pEncoding.Append(imapTerms);
}
PR_FREEIF(csname);
return err;

View File

@ -21,6 +21,7 @@
*/
#include "msgCore.h"
#include "nsTextFormatter.h"
#include "nsMsgSearchCore.h"
#include "nsMsgSearchAdapter.h"
#include "nsMsgSearchScopeTerm.h"
@ -129,7 +130,9 @@ NS_IMETHODIMP nsMsgSearchAdapter::AddHit(nsMsgKey key)
char *
nsMsgSearchAdapter::TryToConvertCharset(const char *sourceStr, const PRUnichar *srcCharset, const PRUnichar * destCharset, PRBool useMime2)
nsMsgSearchAdapter::TryToConvertCharset(const PRUnichar *sourceStr,
const PRUnichar * destCharset,
PRBool useMime2)
{
char *result = nsnull;
@ -198,23 +201,24 @@ nsMsgSearchAdapter::GetImapCharsetParam(const PRUnichar *destCharset)
return result;
}
char *nsMsgSearchAdapter::EscapeSearchUrl (const char *nntpCommand)
PRUnichar *nsMsgSearchAdapter::EscapeSearchUrl (const PRUnichar *nntpCommand)
{
char *result = nsnull;
PRUnichar *result = nsnull;
// max escaped length is two extra characters for every character in the cmd.
char *scratchBuf = (char*) PR_Malloc(3*nsCRT::strlen(nntpCommand) + 1);
PRUnichar *scratchBuf = (PRUnichar*) PR_Malloc(3*nsCRT::strlen(nntpCommand) + 1);
if (scratchBuf)
{
char *scratchPtr = scratchBuf;
PRUnichar *scratchPtr = scratchBuf;
while (PR_TRUE)
{
char ch = *nntpCommand++;
PRUnichar ch = *nntpCommand++;
if (!ch)
break;
if (ch == '#' || ch == '?' || ch == '@' || ch == '\\')
{
*scratchPtr++ = '\\';
sprintf (scratchPtr, "%X", ch);
nsTextFormatter::snprintf(scratchPtr, 2,
NS_ConvertASCIItoUCS2("%2.2X").GetUnicode(), ch);
/* Reviewed 4.51 safe use of sprintf */
scratchPtr += 2;
}
@ -222,51 +226,55 @@ char *nsMsgSearchAdapter::EscapeSearchUrl (const char *nntpCommand)
*scratchPtr++ = ch;
}
*scratchPtr = '\0';
result = PL_strdup (scratchBuf); // realloc down to smaller size
nsCRT::free (scratchBuf);
result = nsCRT::strdup (scratchBuf); // realloc down to smaller size
nsCRT::free (scratchBuf);
}
return result;
}
char *nsMsgSearchAdapter::EscapeImapSearchProtocol(const char *imapCommand)
PRUnichar *
nsMsgSearchAdapter::EscapeImapSearchProtocol(const PRUnichar *imapCommand)
{
char *result = nsnull;
PRUnichar *result = nsnull;
// max escaped length is one extra character for every character in the cmd.
char *scratchBuf = (char*) PR_Malloc (2*nsCRT::strlen(imapCommand) + 1);
PRUnichar *scratchBuf =
(PRUnichar*) PR_Malloc (2*nsCRT::strlen(imapCommand) + 1);
if (scratchBuf)
{
char *scratchPtr = scratchBuf;
PRUnichar *scratchPtr = scratchBuf;
while (1)
{
char ch = *imapCommand++;
PRUnichar ch = *imapCommand++;
if (!ch)
break;
if (ch == '\\')
if (ch == (PRUnichar)'\\')
{
*scratchPtr++ = '\\';
*scratchPtr++ = '\\';
*scratchPtr++ = (PRUnichar)'\\';
*scratchPtr++ = (PRUnichar)'\\';
}
else
*scratchPtr++ = ch;
}
*scratchPtr = '\0';
result = nsCRT::strdup (scratchBuf); // realloc down to smaller size
nsCRT::free (scratchBuf);
*scratchPtr = 0;
result = nsCRT::strdup (scratchBuf); // realloc down to smaller size
nsCRT::free (scratchBuf);
}
return result;
}
char *nsMsgSearchAdapter::EscapeQuoteImapSearchProtocol(const char *imapCommand)
PRUnichar *
nsMsgSearchAdapter::EscapeQuoteImapSearchProtocol(const PRUnichar *imapCommand)
{
char *result = nsnull;
PRUnichar *result = nsnull;
// max escaped length is one extra character for every character in the cmd.
char *scratchBuf = (char*) PR_Malloc (2*nsCRT::strlen(imapCommand) + 1);
PRUnichar *scratchBuf =
(PRUnichar*) PR_Malloc (2*nsCRT::strlen(imapCommand) + 1);
if (scratchBuf)
{
char *scratchPtr = scratchBuf;
PRUnichar *scratchPtr = scratchBuf;
while (1)
{
char ch = *imapCommand++;
PRUnichar ch = *imapCommand++;
if (!ch)
break;
if (ch == '"')
@ -556,9 +564,9 @@ nsresult nsMsgSearchAdapter::EncodeImapTerm (nsIMsgSearchTerm *term, PRBool real
if (IsStringAttribute(attrib))
{
char *unconvertedValue; // = reallyDredd ? MSG_EscapeSearchUrl (term->m_value.u.string) : msg_EscapeImapSearchProtocol(term->m_value.u.string);
nsXPIDLCString searchTermValue;
searchValue->GetStr(getter_Copies(searchTermValue));
PRUnichar *convertedValue; // = reallyDredd ? MSG_EscapeSearchUrl (term->m_value.u.string) : msg_EscapeImapSearchProtocol(term->m_value.u.string);
nsXPIDLString searchTermValue;
searchValue->GetStr(getter_Copies(searchTermValue));
// Ugly switch for Korean mail/news charsets.
// We want to do this here because here is where
// we know what charset we want to use.
@ -569,25 +577,28 @@ nsresult nsMsgSearchAdapter::EncodeImapTerm (nsIMsgSearchTerm *term, PRBool real
dest_csid = INTL_DefaultMailCharSetID(dest_csid);
#endif
unconvertedValue = TryToConvertCharset((const char *) searchTermValue,
srcCharset,
destCharset,
reallyDredd);
if (!unconvertedValue)
unconvertedValue = nsCRT::strdup((const char *) searchTermValue); // couldn't convert, send as is
value = reallyDredd ? EscapeSearchUrl (unconvertedValue) : EscapeImapSearchProtocol(unconvertedValue);
PR_Free(unconvertedValue);
valueWasAllocated = PR_TRUE;
useQuotes = !reallyDredd || (PL_strchr(value, ' ') != nsnull);
// do all sorts of crazy escaping
convertedValue = reallyDredd ? EscapeSearchUrl (searchTermValue) :
EscapeImapSearchProtocol(searchTermValue);
useQuotes = !reallyDredd ||
(nsAutoString(convertedValue).FindChar((PRUnichar)' ') != -1);
if (useQuotes)
{
unconvertedValue = value;
value = EscapeQuoteImapSearchProtocol(unconvertedValue);
PR_Free(unconvertedValue);
PRUnichar *oldConvertedValue = convertedValue;
convertedValue = EscapeQuoteImapSearchProtocol(convertedValue);
nsCRT::free(oldConvertedValue);
}
// now convert to char*
value = TryToConvertCharset(convertedValue, destCharset, reallyDredd);
// if couldn't convert, send as is
if (!value)
value = NS_ConvertUCS2toUTF8(convertedValue).ToNewCString();
nsCRT::free(convertedValue);
valueWasAllocated = PR_TRUE;
}
}

View File

@ -38,7 +38,9 @@ public:
NS_IMETHOD GetEncoding (char **result);
NS_IMETHOD AddResultElement (nsIMsgDBHdr *);
static nsresult Encode (nsCString *ppEncoding, nsISupportsArray *searchTerms, const PRUnichar *srcCharset, const PRUnichar *destCharset);
static nsresult Encode (nsCString& ppEncoding,
nsISupportsArray *searchTerms,
const PRUnichar *destCharset);
protected:

View File

@ -75,30 +75,30 @@ nsresult nsMsgSearchNews::Search (PRBool *aDone)
}
char *nsMsgSearchNews::EncodeValue (const char *value)
PRUnichar *nsMsgSearchNews::EncodeToWildmat (const PRUnichar *value)
{
// Here we take advantage of XPAT's use of the wildmat format, which allows
// a case-insensitive match by specifying each case possibility for each character
// So, "FooBar" is encoded as "[Ff][Oo][Bb][Aa][Rr]"
char *caseInsensitiveValue = (char*) PR_Malloc ((4 * nsCRT::strlen(value)) + 1);
PRUnichar *caseInsensitiveValue = (PRUnichar*) PR_Malloc ((4 * nsCRT::strlen(value)) + 1);
if (caseInsensitiveValue)
{
char *walkValue = caseInsensitiveValue;
PRUnichar *walkValue = caseInsensitiveValue;
while (*value)
{
if (nsCRT::IsAsciiAlpha(*value))
{
*walkValue++ = '[';
*walkValue++ = (char)nsCRT::ToUpper((PRUnichar)*value);
*walkValue++ = (char)nsCRT::ToLower((PRUnichar)*value);
*walkValue++ = ']';
*walkValue++ = (PRUnichar)'[';
*walkValue++ = nsCRT::ToUpper((PRUnichar)*value);
*walkValue++ = nsCRT::ToLower((PRUnichar)*value);
*walkValue++ = (PRUnichar)']';
}
else
*walkValue++ = *value;
value++;
}
*walkValue = '\0';
*walkValue = 0;
}
return caseInsensitiveValue;
}
@ -172,13 +172,12 @@ char *nsMsgSearchNews::EncodeTerm (nsIMsgSearchTerm *term)
return nsnull;
char *intlNonRFC1522Value = nsnull;
rv = searchValue->GetStr(&intlNonRFC1522Value);
nsXPIDLString intlNonRFC1522Value;
rv = searchValue->GetStr(getter_Copies(intlNonRFC1522Value));
if (!NS_SUCCEEDED(rv) || !intlNonRFC1522Value)
return nsnull;
char *caseInsensitiveValue = EncodeValue ((char*)intlNonRFC1522Value);
nsCRT::free(intlNonRFC1522Value);
PRUnichar *caseInsensitiveValue = EncodeToWildmat (intlNonRFC1522Value);
if (!caseInsensitiveValue)
return nsnull;
@ -187,42 +186,44 @@ char *nsMsgSearchNews::EncodeTerm (nsIMsgSearchTerm *term)
// Need to add the INTL_FormatNNTPXPATInRFC1522Format call after we can do that
// so we should search a string in either RFC1522 format and non-RFC1522 format
char *escapedValue = EscapeSearchUrl (caseInsensitiveValue);
PRUnichar *escapedValue = EscapeSearchUrl (caseInsensitiveValue);
nsCRT::free(caseInsensitiveValue);
if (!escapedValue)
return nsnull;
#if 0
// We also need to apply NET_Escape to it since we have to pass 8-bits data
// And sometimes % in the 7-bit doulbe byte JIS
//
char * urlEncoded = nsEscape((char*)escapedValue, url_Path);
PRUnichar * urlEncoded = nsEscape(escapedValue, url_Path);
nsCRT::free(escapedValue);
if (! urlEncoded)
return nsnull;
char *pattern = pattern = new char [nsCRT::strlen(urlEncoded) + overhead];
char *pattern = new char [nsCRT::strlen(urlEncoded) + overhead];
if (!pattern)
return nsnull;
else
pattern[0] = '\0';
#else
nsCAutoString pattern;
#endif
if (leadingStar)
PL_strcat (pattern, "*");
PL_strcat (pattern, urlEncoded);
pattern.Append("*");
pattern.Append(NS_ConvertUCS2toUTF8(escapedValue));
if (trailingStar)
PL_strcat (pattern, "*");
pattern.Append("*");
// Combine the XPAT command syntax with the attribute and the pattern to
// form the term encoding
char *xpatTemplate = "XPAT %s 1- %s";
int termLength = nsCRT::strlen(xpatTemplate) + nsCRT::strlen(attribEncoding) + nsCRT::strlen(pattern) + 1;
int termLength = nsCRT::strlen(xpatTemplate) + nsCRT::strlen(attribEncoding) + pattern.Length() + 1;
char *termEncoding = new char [termLength];
if (termEncoding)
PR_snprintf (termEncoding, termLength, xpatTemplate, attribEncoding, pattern);
nsCRT::free(urlEncoded);
delete [] pattern;
PR_snprintf (termEncoding, termLength, xpatTemplate, attribEncoding, pattern.GetBuffer());
return termEncoding;
}

View File

@ -40,7 +40,7 @@ public:
virtual nsresult Encode (nsCString *outEncoding);
virtual char *EncodeTerm (nsIMsgSearchTerm *);
char *EncodeValue (const char *);
PRUnichar *EncodeToWildmat (const PRUnichar *);
PRBool DuplicateHit(PRUint32 artNum) ;
void CollateHits ();

View File

@ -21,6 +21,8 @@
*/
#include "msgCore.h"
#include "nsXPIDLString.h"
#include "nsMsgSearchCore.h"
#include "nsIMsgSearchSession.h"
#include "nsMsgUtils.h"
@ -34,6 +36,7 @@
#include "nsMsgLocalSearch.h"
#include "nsMsgSearchNews.h"
#include "nsMsgSearchValue.h"
//---------------------------------------------------------------------------
// nsMsgSearchTerm specifies one criterion, e.g. name contains phil
//---------------------------------------------------------------------------
@ -282,7 +285,7 @@ nsMsgSearchTerm::nsMsgSearchTerm (
nsMsgSearchTerm::~nsMsgSearchTerm ()
{
if (IS_STRING_ATTRIBUTE (m_attribute) && m_value.string)
PR_Free(m_value.string);
Recycle(m_value.string);
}
NS_IMPL_ISUPPORTS1(nsMsgSearchTerm, nsIMsgSearchTerm)
@ -784,7 +787,7 @@ nsresult nsMsgSearchTerm::MatchString (const char *stringToMatch,
if(nsMsgSearchOp::IsEmpty != m_operator) // Save some performance for opIsEmpty
{
#ifdef DO_I18N
n_str = INTL_GetNormalizeStr(csid , (unsigned char*)m_value.u.string); // Always new buffer unless not enough memory
n_str = INTL_GetNormalizeStr(csid , (unsigned char*)m_value.string); // Always new buffer unless not enough memory
if (!body)
n_header = INTL_GetNormalizeStrFromRFC1522(csid , stringToMatch); // Always new buffer unless not enough memory
else
@ -1460,7 +1463,9 @@ nsresult nsMsgResultElement::AssignValues (nsIMsgSearchValue *src, nsMsgSearchVa
if (dst->attribute < nsMsgSearchAttrib::kNumMsgSearchAttributes)
{
NS_ASSERTION(IS_STRING_ATTRIBUTE(dst->attribute), "assigning non-string result");
err = src->GetStr(&dst->string);
nsXPIDLString unicodeString;
err = src->GetStr(getter_Copies(unicodeString));
dst->string = NS_ConvertUCS2toUTF8(unicodeString).ToNewCString();
}
else
err = NS_ERROR_INVALID_ARG;
@ -1574,7 +1579,7 @@ nsresult nsMsgResultElement::GetPrettyName (nsMsgSearchValue **value)
if (tmp)
{
XP_FREE ((*value)->u.string);
(*value)->u.string = tmp;
(*value)->u.utf8SstringZ = tmp;
}
}
}

View File

@ -30,6 +30,8 @@ nsMsgSearchValueImpl::nsMsgSearchValueImpl(nsMsgSearchValue *aInitialValue)
mValue = *aInitialValue;
if (IS_STRING_ATTRIBUTE(aInitialValue->attribute))
mValue.string = nsCRT::strdup(aInitialValue->string);
else
mValue.string = 0;
}
nsMsgSearchValueImpl::~nsMsgSearchValueImpl()
@ -42,21 +44,21 @@ nsMsgSearchValueImpl::~nsMsgSearchValueImpl()
NS_IMPL_ISUPPORTS1(nsMsgSearchValueImpl, nsIMsgSearchValue)
NS_IMETHODIMP
nsMsgSearchValueImpl::GetStr(char** aResult)
nsMsgSearchValueImpl::GetStr(PRUnichar** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_TRUE(IS_STRING_ATTRIBUTE(mValue.attribute), NS_ERROR_ILLEGAL_VALUE);
*aResult = nsCRT::strdup(mValue.string);
*aResult = NS_ConvertUTF8toUCS2(mValue.string).ToNewUnicode();
return NS_OK;
}
NS_IMETHODIMP
nsMsgSearchValueImpl::SetStr(const char* aValue)
nsMsgSearchValueImpl::SetStr(const PRUnichar* aValue)
{
NS_ENSURE_TRUE(IS_STRING_ATTRIBUTE(mValue.attribute), NS_ERROR_ILLEGAL_VALUE);
if (mValue.string)
nsCRT::free(mValue.string);
mValue.string = nsCRT::strdup(aValue);
mValue.string = NS_ConvertUCS2toUTF8(aValue).ToNewCString();
return NS_OK;
}
@ -198,10 +200,11 @@ NS_IMETHODIMP
nsMsgSearchValueImpl::ToString(PRUnichar **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
nsAutoString resultStr;
resultStr.AssignWithConversion("[nsIMsgSearchValue: ");
if (IS_STRING_ATTRIBUTE(mValue.attribute)) {
nsCAutoString str(mValue.string);
*aResult = str.ToNewUnicode();
resultStr.Append(NS_ConvertUTF8toUCS2(mValue.string));
return NS_OK;
}
@ -215,11 +218,15 @@ nsMsgSearchValueImpl::ToString(PRUnichar **aResult)
case nsMsgSearchAttrib::Size:
case nsMsgSearchAttrib::AgeInDays:
case nsMsgSearchAttrib::FolderInfo:
*aResult = nsnull;
resultStr.AppendWithConversion("type=");
resultStr.AppendInt(mValue.attribute);
break;
default:
NS_ASSERTION(0, "Unknown search value type");
}
resultStr.AppendWithConversion("]");
*aResult = resultStr.ToNewUnicode();
return NS_OK;
}