From 3d0478f5698ecfd387526d1d7c1784d2a979f663 Mon Sep 17 00:00:00 2001 From: "bienvenu%nventure.com" Date: Thu, 10 May 2007 15:12:39 +0000 Subject: [PATCH] remove more xpidl strings, 379070, sr=mscott --- mailnews/base/search/src/nsMsgSearchTerm.cpp | 3428 ++++++++--------- mailnews/base/util/nsMsgDBFolder.cpp | 7 +- mailnews/base/util/nsMsgDBFolder.h | 2 +- mailnews/imap/src/nsIMAPBodyShell.cpp | 4 +- mailnews/imap/src/nsImapIncomingServer.cpp | 81 +- mailnews/imap/src/nsImapMailFolder.cpp | 2 +- mailnews/imap/src/nsImapOfflineSync.cpp | 21 +- mailnews/imap/src/nsImapProtocol.cpp | 261 +- mailnews/imap/src/nsImapProtocol.h | 33 +- .../imap/src/nsImapServerResponseParser.cpp | 14 +- mailnews/imap/src/nsImapService.cpp | 286 +- mailnews/imap/src/nsImapUndoTxn.cpp | 13 +- mailnews/imap/src/nsImapUrl.cpp | 23 +- mailnews/imap/src/nsImapUrl.h | 1 - mailnews/imap/src/nsImapUtils.cpp | 15 +- mailnews/imap/src/nsImapUtils.h | 2 +- mailnews/local/src/nsLocalMailFolder.cpp | 6 +- mailnews/local/src/nsLocalUtils.cpp | 13 +- mailnews/local/src/nsLocalUtils.h | 2 +- mailnews/local/src/nsMailboxUrl.cpp | 7 +- mailnews/news/src/nsNewsFolder.cpp | 2 +- mailnews/news/src/nsNewsUtils.cpp | 23 +- mailnews/news/src/nsNewsUtils.h | 2 +- 23 files changed, 2087 insertions(+), 2161 deletions(-) diff --git a/mailnews/base/search/src/nsMsgSearchTerm.cpp b/mailnews/base/search/src/nsMsgSearchTerm.cpp index 37be64051f0..30df31fac34 100644 --- a/mailnews/base/search/src/nsMsgSearchTerm.cpp +++ b/mailnews/base/search/src/nsMsgSearchTerm.cpp @@ -1,1717 +1,1717 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Seth Spitzer - * Jungshik Shin - * David Bienvenu - * - * 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"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "msgCore.h" -#include "nsXPIDLString.h" -#include "nsReadableUtils.h" - -#include "nsMsgSearchCore.h" -#include "nsIMsgSearchSession.h" -#include "nsMsgUtils.h" -#include "nsIMsgDatabase.h" -#include "nsMsgSearchTerm.h" -#include "nsMsgSearchScopeTerm.h" -#include "nsMsgBodyHandler.h" -#include "nsMsgResultElement.h" -#include "nsIMsgImapMailFolder.h" -#include "nsMsgSearchImap.h" -#include "nsMsgLocalSearch.h" -#include "nsMsgSearchNews.h" -#include "nsMsgSearchValue.h" -#include "nsMsgI18N.h" -#include "nsIMimeConverter.h" -#include "nsMsgMimeCID.h" -#include "nsTime.h" -#include "nsIPrefBranch.h" -#include "nsIPrefService.h" -#include "nsIMsgFilterPlugin.h" -#include "nsILocalFile.h" -#include "nsIRDFService.h" -#include "nsISupportsObsolete.h" -#include "nsNetCID.h" -#include "nsIFileStreams.h" -#include "nsUnicharUtils.h" -//--------------------------------------------------------------------------- -// nsMsgSearchTerm specifies one criterion, e.g. name contains phil -//--------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -//-------------------- Implementation of nsMsgSearchTerm ----------------------- -//----------------------------------------------------------------------------- -#define MAILNEWS_CUSTOM_HEADERS "mailnews.customHeaders" - -typedef struct -{ - nsMsgSearchAttribValue attrib; - const char *attribName; -} nsMsgSearchAttribEntry; - -nsMsgSearchAttribEntry SearchAttribEntryTable[] = -{ - {nsMsgSearchAttrib::Subject, "subject"}, - {nsMsgSearchAttrib::Sender, "from"}, - {nsMsgSearchAttrib::Body, "body"}, - {nsMsgSearchAttrib::Date, "date"}, - {nsMsgSearchAttrib::Priority, "priority"}, - {nsMsgSearchAttrib::MsgStatus, "status"}, - {nsMsgSearchAttrib::To, "to"}, - {nsMsgSearchAttrib::CC, "cc"}, - {nsMsgSearchAttrib::ToOrCC, "to or cc"}, - {nsMsgSearchAttrib::AgeInDays, "age in days"}, - {nsMsgSearchAttrib::Label, "label"}, - {nsMsgSearchAttrib::Keywords, "tag"}, - {nsMsgSearchAttrib::Size, "size"}, - // this used to be nsMsgSearchAttrib::SenderInAddressBook - // we used to have two Sender menuitems - // for backward compatability, we can still parse - // the old style. see bug #179803 - {nsMsgSearchAttrib::Sender, "from in ab"}, - {nsMsgSearchAttrib::JunkStatus, "junk status"}, - {nsMsgSearchAttrib::HasAttachmentStatus, "has attachment status"}, -}; - -// Take a string which starts off with an attribute -// return the matching attribute. If the string is not in the table, then we can conclude that it is an arbitrary header -nsresult NS_MsgGetAttributeFromString(const char *string, PRInt16 *attrib) -{ - NS_ENSURE_ARG_POINTER(string); - NS_ENSURE_ARG_POINTER(attrib); - - PRBool found = PR_FALSE; - for (int idxAttrib = 0; idxAttrib < (int)(sizeof(SearchAttribEntryTable) / sizeof(nsMsgSearchAttribEntry)); idxAttrib++) - { - if (!PL_strcasecmp(string, SearchAttribEntryTable[idxAttrib].attribName)) - { - found = PR_TRUE; - *attrib = SearchAttribEntryTable[idxAttrib].attrib; - break; - } - } - if (!found) - { - nsresult rv; - PRBool goodHdr; - IsRFC822HeaderFieldName(string, &goodHdr); - if (!goodHdr) - return NS_MSG_INVALID_CUSTOM_HEADER; - //49 is for showing customize... in ui, headers start from 50 onwards up until 99. - *attrib = nsMsgSearchAttrib::OtherHeader+1; - - nsCOMPtr prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr prefBranch; - rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch)); - NS_ENSURE_SUCCESS(rv, rv); - - nsXPIDLCString headers; - prefBranch->GetCharPref(MAILNEWS_CUSTOM_HEADERS, getter_Copies(headers)); - - if (!headers.IsEmpty()) - { - char *headersString = ToNewCString(headers); - - nsCAutoString hdrStr; - hdrStr.Adopt(headersString); - hdrStr.StripWhitespace(); //remove whitespace before parsing - - char *newStr=nsnull; - char *token = nsCRT::strtok(headersString,":", &newStr); - PRUint32 i=0; - while (token) - { - if (nsCRT::strcasecmp(token, string) == 0) - { - *attrib += i; //we found custom header in the pref - found = PR_TRUE; - break; - } - token = nsCRT::strtok(newStr,":", &newStr); - i++; - } - } - } - // If we didn't find the header in MAILNEWS_CUSTOM_HEADERS, we're - // going to return NS_OK and an attrib of nsMsgSearchAttrib::OtherHeader+1. - // in case it's a client side spam filter description filter, - // which doesn't add its headers to mailnews.customMailHeaders. - // We've already checked that it's a valid header and returned - // an error if so. - - return NS_OK; -} - -nsresult NS_MsgGetStringForAttribute(PRInt16 attrib, const char **string) -{ - NS_ENSURE_ARG_POINTER(string); - - PRBool found = PR_FALSE; - for (int idxAttrib = 0; idxAttrib < (int)(sizeof(SearchAttribEntryTable) / sizeof(nsMsgSearchAttribEntry)); idxAttrib++) - { - // I'm using the idx's as aliases into MSG_SearchAttribute and - // MSG_SearchOperator enums which is legal because of the way the - // enums are defined (starts at 0, numItems at end) - if (attrib == SearchAttribEntryTable[idxAttrib].attrib) - { - found = PR_TRUE; - *string = SearchAttribEntryTable[idxAttrib].attribName; - break; - } - } - // we no longer return invalid attribute. If we cannot find the string in the table, - // then it is an arbitrary header. Return success regardless if found or not - return NS_OK; -} - -typedef struct -{ - nsMsgSearchOpValue op; - const char *opName; -} nsMsgSearchOperatorEntry; - -nsMsgSearchOperatorEntry SearchOperatorEntryTable[] = -{ - {nsMsgSearchOp::Contains, "contains"}, - {nsMsgSearchOp::DoesntContain,"doesn't contain"}, - {nsMsgSearchOp::Is,"is"}, - {nsMsgSearchOp::Isnt, "isn't"}, - {nsMsgSearchOp::IsEmpty, "is empty"}, - {nsMsgSearchOp::IsBefore, "is before"}, - {nsMsgSearchOp::IsAfter, "is after"}, - {nsMsgSearchOp::IsHigherThan, "is higher than"}, - {nsMsgSearchOp::IsLowerThan, "is lower than"}, - {nsMsgSearchOp::BeginsWith, "begins with"}, - {nsMsgSearchOp::EndsWith, "ends with"}, - {nsMsgSearchOp::IsInAB, "is in ab"}, - {nsMsgSearchOp::IsntInAB, "isn't in ab"}, - {nsMsgSearchOp::IsGreaterThan, "is greater than"}, - {nsMsgSearchOp::IsLessThan, "is less than"} -}; - -nsresult NS_MsgGetOperatorFromString(const char *string, PRInt16 *op) -{ - NS_ENSURE_ARG_POINTER(string); - NS_ENSURE_ARG_POINTER(op); - - PRBool found = PR_FALSE; - for (unsigned int idxOp = 0; idxOp < sizeof(SearchOperatorEntryTable) / sizeof(nsMsgSearchOperatorEntry); idxOp++) - { - // I'm using the idx's as aliases into MSG_SearchAttribute and - // MSG_SearchOperator enums which is legal because of the way the - // enums are defined (starts at 0, numItems at end) - if (!PL_strcasecmp(string, SearchOperatorEntryTable[idxOp].opName)) - { - found = PR_TRUE; - *op = SearchOperatorEntryTable[idxOp].op; - break; - } - } - return (found) ? NS_OK : NS_ERROR_INVALID_ARG; -} - -nsresult NS_MsgGetStringForOperator(PRInt16 op, const char **string) -{ - NS_ENSURE_ARG_POINTER(string); - - PRBool found = PR_FALSE; - for (unsigned int idxOp = 0; idxOp < sizeof(SearchOperatorEntryTable) / sizeof(nsMsgSearchOperatorEntry); idxOp++) - { - // I'm using the idx's as aliases into MSG_SearchAttribute and - // MSG_SearchOperator enums which is legal because of the way the - // enums are defined (starts at 0, numItems at end) - if (op == SearchOperatorEntryTable[idxOp].op) - { - found = PR_TRUE; - *string = SearchOperatorEntryTable[idxOp].opName; - break; - } - } - - return (found) ? NS_OK : NS_ERROR_INVALID_ARG; -} - -void NS_MsgGetUntranslatedStatusName (uint32 s, nsCString *outName) -{ - const char *tmpOutName = NULL; -#define MSG_STATUS_MASK (MSG_FLAG_READ | MSG_FLAG_REPLIED | MSG_FLAG_FORWARDED | MSG_FLAG_NEW | MSG_FLAG_MARKED) - PRUint32 maskOut = (s & MSG_STATUS_MASK); - - // diddle the flags to pay attention to the most important ones first, if multiple - // flags are set. Should remove this code from the winfe. - if (maskOut & MSG_FLAG_NEW) - maskOut = MSG_FLAG_NEW; - if ( maskOut & MSG_FLAG_REPLIED && - maskOut & MSG_FLAG_FORWARDED ) - maskOut = MSG_FLAG_REPLIED|MSG_FLAG_FORWARDED; - else if ( maskOut & MSG_FLAG_FORWARDED ) - maskOut = MSG_FLAG_FORWARDED; - else if ( maskOut & MSG_FLAG_REPLIED ) - maskOut = MSG_FLAG_REPLIED; - - switch (maskOut) - { - case MSG_FLAG_READ: - tmpOutName = "read"; - break; - case MSG_FLAG_REPLIED: - tmpOutName = "replied"; - break; - case MSG_FLAG_FORWARDED: - tmpOutName = "forwarded"; - break; - case MSG_FLAG_FORWARDED|MSG_FLAG_REPLIED: - tmpOutName = "replied and forwarded"; - break; - case MSG_FLAG_NEW: - tmpOutName = "new"; - break; - case MSG_FLAG_MARKED: - tmpOutName = "flagged"; - break; - default: - // This is fine, status may be "unread" for example - break; - } - - if (tmpOutName) - *outName = tmpOutName; -} - - -PRInt32 NS_MsgGetStatusValueFromName(char *name) -{ - if (!strcmp("read", name)) - return MSG_FLAG_READ; - if (!strcmp("replied", name)) - return MSG_FLAG_REPLIED; - if (!strcmp("forwarded", name)) - return MSG_FLAG_FORWARDED; - if (!strcmp("replied and forwarded", name)) - return MSG_FLAG_FORWARDED|MSG_FLAG_REPLIED; - if (!strcmp("new", name)) - return MSG_FLAG_NEW; - if (!strcmp("flagged", name)) - return MSG_FLAG_MARKED; - return 0; -} - - -// Needed for DeStream method. -nsMsgSearchTerm::nsMsgSearchTerm() -{ - // initialize this to zero - m_value.string=nsnull; - m_value.attribute=0; - m_value.u.priority=0; - m_attribute = nsMsgSearchAttrib::Default; - mBeginsGrouping = PR_FALSE; - mEndsGrouping = PR_FALSE; - m_matchAll = PR_FALSE; -} - -nsMsgSearchTerm::nsMsgSearchTerm ( - nsMsgSearchAttribValue attrib, - nsMsgSearchOpValue op, - nsIMsgSearchValue *val, - nsMsgSearchBooleanOperator boolOp, - const char * arbitraryHeader) -{ - m_operator = op; - m_attribute = attrib; - m_booleanOp = boolOp; - if (attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes && arbitraryHeader) - m_arbitraryHeader = arbitraryHeader; - nsMsgResultElement::AssignValues (val, &m_value); - m_matchAll = PR_FALSE; -} - - - -nsMsgSearchTerm::~nsMsgSearchTerm () -{ - if (IS_STRING_ATTRIBUTE (m_attribute) && m_value.string) - Recycle(m_value.string); -} - -NS_IMPL_ISUPPORTS1(nsMsgSearchTerm, nsIMsgSearchTerm) - - -// Perhaps we could find a better place for this? -// Caller needs to free. -/* static */char *nsMsgSearchTerm::EscapeQuotesInStr(const char *str) -{ - int numQuotes = 0; - for (const char *strPtr = str; *strPtr; strPtr++) - if (*strPtr == '"') - numQuotes++; - int escapedStrLen = PL_strlen(str) + numQuotes; - char *escapedStr = (char *) PR_Malloc(escapedStrLen + 1); - if (escapedStr) - { - char *destPtr; - for (destPtr = escapedStr; *str; str++) - { - if (*str == '"') - *destPtr++ = '\\'; - *destPtr++ = *str; - } - *destPtr = '\0'; - } - return escapedStr; -} - - -nsresult nsMsgSearchTerm::OutputValue(nsCString &outputStr) -{ - if (IS_STRING_ATTRIBUTE(m_attribute) && m_value.string) - { - PRBool quoteVal = PR_FALSE; - // need to quote strings with ')' and strings starting with '"' or ' ' - // filter code will escape quotes - if (PL_strchr(m_value.string, ')') || - (m_value.string[0] == ' ') || - (m_value.string[0] == '"')) - { - quoteVal = PR_TRUE; - outputStr += "\""; - } - if (PL_strchr(m_value.string, '"')) - { - char *escapedString = nsMsgSearchTerm::EscapeQuotesInStr(m_value.string); - if (escapedString) - { - outputStr += escapedString; - PR_Free(escapedString); - } - - } - else - { - outputStr += m_value.string; - } - if (quoteVal) - outputStr += "\""; - } - else - { - switch (m_attribute) - { - case nsMsgSearchAttrib::Date: - { - PRExplodedTime exploded; - PR_ExplodeTime(m_value.u.date, PR_LocalTimeParameters, &exploded); - - // wow, so tm_mon is 0 based, tm_mday is 1 based. - char dateBuf[100]; - PR_FormatTimeUSEnglish (dateBuf, sizeof(dateBuf), "%d-%b-%Y", &exploded); - outputStr += dateBuf; - break; - } - case nsMsgSearchAttrib::AgeInDays: - { - outputStr.AppendInt(m_value.u.age); - break; - } - case nsMsgSearchAttrib::Label: - { - outputStr.AppendInt(m_value.u.label); - break; - } - case nsMsgSearchAttrib::JunkStatus: - { - outputStr.AppendInt(m_value.u.junkStatus); // only if we write to disk, right? - break; - } - case nsMsgSearchAttrib::MsgStatus: - { - nsCAutoString status; - NS_MsgGetUntranslatedStatusName (m_value.u.msgStatus, &status); - outputStr += status; - break; - } - case nsMsgSearchAttrib::Priority: - { - nsCAutoString priority; - NS_MsgGetUntranslatedPriorityName(m_value.u.priority, priority); - outputStr += priority; - break; - } - case nsMsgSearchAttrib::HasAttachmentStatus: - { - outputStr.Append("true"); // don't need anything here, really - break; - } - case nsMsgSearchAttrib::Size: - { - outputStr.AppendInt(m_value.u.size); - break; - } - default: - NS_ASSERTION(PR_FALSE, "trying to output invalid attribute"); - break; - } - } - return NS_OK; -} - -NS_IMETHODIMP nsMsgSearchTerm::GetTermAsString (nsACString &outStream) -{ - const char *attrib, *operatorStr; - nsCAutoString outputStr; - nsresult ret; - - if (m_matchAll) - { - outStream = "ALL"; - return NS_OK; - } - ret = NS_MsgGetStringForAttribute(m_attribute, &attrib); - if (ret != NS_OK) - return ret; - - if (m_attribute > nsMsgSearchAttrib::OtherHeader && m_attribute < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if arbitrary header, use it instead! - { - outputStr = "\""; - outputStr += m_arbitraryHeader; - outputStr += "\""; - } - else - outputStr = attrib; - - outputStr += ','; - - ret = NS_MsgGetStringForOperator(m_operator, &operatorStr); - if (ret != NS_OK) - return ret; - - outputStr += operatorStr; - outputStr += ','; - - OutputValue(outputStr); - outStream = outputStr; - return NS_OK; -} - -// fill in m_value from the input stream. -nsresult nsMsgSearchTerm::ParseValue(char *inStream) -{ - if (IS_STRING_ATTRIBUTE(m_attribute)) - { - PRBool quoteVal = PR_FALSE; - while (nsCRT::IsAsciiSpace(*inStream)) - inStream++; - // need to remove pair of '"', if present - if (*inStream == '"') - { - quoteVal = PR_TRUE; - inStream++; - } - int valueLen = PL_strlen(inStream); - if (quoteVal && inStream[valueLen - 1] == '"') - valueLen--; - - m_value.string = (char *) PR_Malloc(valueLen + 1); - PL_strncpy(m_value.string, inStream, valueLen + 1); - m_value.string[valueLen] = '\0'; - } - else - { - switch (m_attribute) - { - case nsMsgSearchAttrib::Date: - PR_ParseTimeString (inStream, PR_FALSE, &m_value.u.date); - break; - case nsMsgSearchAttrib::MsgStatus: - m_value.u.msgStatus = NS_MsgGetStatusValueFromName(inStream); - break; - case nsMsgSearchAttrib::Priority: - NS_MsgGetPriorityFromString(inStream, m_value.u.priority); - break; - case nsMsgSearchAttrib::AgeInDays: - m_value.u.age = atoi(inStream); - break; - case nsMsgSearchAttrib::Label: - m_value.u.label = atoi(inStream); - break; - case nsMsgSearchAttrib::JunkStatus: - m_value.u.junkStatus = atoi(inStream); // only if we read from disk, right? - break; - case nsMsgSearchAttrib::HasAttachmentStatus: - m_value.u.msgStatus = MSG_FLAG_ATTACHMENT; - break; // this should always be true. - case nsMsgSearchAttrib::Size: - m_value.u.size = atoi(inStream); - break; - default: - NS_ASSERTION(PR_FALSE, "invalid attribute parsing search term value"); - break; - } - } - m_value.attribute = m_attribute; - return NS_OK; -} - -// find the operator code for this operator string. -nsresult -nsMsgSearchTerm::ParseOperator(char *inStream, nsMsgSearchOpValue *value) -{ - NS_ENSURE_ARG_POINTER(value); - PRInt16 operatorVal; - while (nsCRT::IsAsciiSpace(*inStream)) - inStream++; - - char *commaSep = PL_strchr(inStream, ','); - - if (commaSep) - *commaSep = '\0'; - - nsresult err = NS_MsgGetOperatorFromString(inStream, &operatorVal); - *value = (nsMsgSearchOpValue) operatorVal; - return err; -} - -// find the attribute code for this comma-delimited attribute. -nsresult -nsMsgSearchTerm::ParseAttribute(char *inStream, nsMsgSearchAttribValue *attrib) -{ - while (nsCRT::IsAsciiSpace(*inStream)) - inStream++; - - // if we are dealing with an arbitrary header, it may be quoted.... - PRBool quoteVal = PR_FALSE; - if (*inStream == '"') - { - quoteVal = PR_TRUE; - inStream++; - } - - // arbitrary headers are quoted - char *separator = strchr(inStream, quoteVal ? '"' : ','); - - if (separator) - *separator = '\0'; - - PRInt16 attributeVal; - nsresult rv = NS_MsgGetAttributeFromString(inStream, &attributeVal); - NS_ENSURE_SUCCESS(rv, rv); - - *attrib = (nsMsgSearchAttribValue) attributeVal; - - if (*attrib > nsMsgSearchAttrib::OtherHeader && *attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if we are dealing with an arbitrary header.... - m_arbitraryHeader = inStream; - - return rv; -} - -// De stream one search term. If the condition looks like -// condition = "(to or cc, contains, r-thompson) AND (body, doesn't contain, fred)" -// This routine should get called twice, the first time -// with "to or cc, contains, r-thompson", the second time with -// "body, doesn't contain, fred" - -nsresult nsMsgSearchTerm::DeStreamNew (char *inStream, PRInt16 /*length*/) -{ - if (!strcmp(inStream, "ALL")) - { - m_matchAll = PR_TRUE; - return NS_OK; - } - char *commaSep = PL_strchr(inStream, ','); - nsresult rv = ParseAttribute(inStream, &m_attribute); // will allocate space for arbitrary header if necessary - NS_ENSURE_SUCCESS(rv, rv); - if (!commaSep) - return NS_ERROR_INVALID_ARG; - char *secondCommaSep = PL_strchr(commaSep + 1, ','); - if (commaSep) - rv = ParseOperator(commaSep + 1, &m_operator); - NS_ENSURE_SUCCESS(rv, rv); - // convert label filters and saved searches to keyword equivalents - if (secondCommaSep) - ParseValue(secondCommaSep + 1); - if (m_attribute == nsMsgSearchAttrib::Label) - { - nsCAutoString keyword("$label"); - m_value.attribute = m_attribute = nsMsgSearchAttrib::Keywords; - keyword.Append('0' + m_value.u.label); - m_value.string = PL_strdup(keyword.get()); - } - return NS_OK; -} - - -// Looks in the MessageDB for the user specified arbitrary header, if it finds the header, it then looks for a match against -// the value for the header. -nsresult nsMsgSearchTerm::MatchArbitraryHeader (nsIMsgSearchScopeTerm *scope, - PRUint32 offset, - PRUint32 length /* in lines*/, - const char *charset, - PRBool charsetOverride, - nsIMsgDBHdr *msg, - nsIMsgDatabase* db, - const char * headers, - PRUint32 headersSize, - PRBool ForFiltering, - PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - *pResult = PR_FALSE; - nsresult err = NS_OK; - PRBool result; - - nsMsgBodyHandler * bodyHandler = new nsMsgBodyHandler (scope, offset,length, msg, db, headers, headersSize, ForFiltering); - if (!bodyHandler) - return NS_ERROR_OUT_OF_MEMORY; - - bodyHandler->SetStripHeaders (PR_FALSE); - - GetMatchAllBeforeDeciding(&result); - - nsCAutoString buf; - nsCAutoString curMsgHeader; - PRBool searchingHeaders = PR_TRUE; - while (searchingHeaders && (bodyHandler->GetNextLine(buf) >=0)) - { - char * buf_end = (char *) (buf.get() + buf.Length()); - int headerLength = m_arbitraryHeader.Length(); - PRBool isContinuationHeader = NS_IsAsciiWhitespace(buf.CharAt(0)); - // this handles wrapped header lines, which start with whitespace. - // If the line starts with whitespace, then we use the current header. - if (!isContinuationHeader) - { - PRUint32 colonPos = buf.FindChar(':'); - buf.Left(curMsgHeader, colonPos); - } - - if (curMsgHeader.Equals(m_arbitraryHeader, nsCaseInsensitiveCStringComparator())) - { - // value occurs after the header name or whitespace continuation char. - const char * headerValue = buf.get() + (isContinuationHeader ? 1 : headerLength); - if (headerValue < buf_end && headerValue[0] == ':') // + 1 to account for the colon which is MANDATORY - headerValue++; - - // strip leading white space - while (headerValue < buf_end && nsCRT::IsAsciiSpace(*headerValue)) - headerValue++; // advance to next character - - // strip trailing white space - char * end = buf_end - 1; - while (end > headerValue && nsCRT::IsAsciiSpace(*end)) // while we haven't gone back past the start and we are white space.... - { - *end = '\0'; // eat up the white space - end--; // move back and examine the previous character.... - } - - if (headerValue < buf_end && *headerValue) // make sure buf has info besides just the header - { - PRBool result2; - err = MatchRfc2047String(headerValue, charset, charsetOverride, &result2); // match value with the other info... - if (result != result2) // if we found a match - { - searchingHeaders = PR_FALSE; // then stop examining the headers - result = result2; - } - } - else - NS_ASSERTION(PR_FALSE, "error matching arbitrary headers"); // mscott --> i'd be curious if there is a case where this fails.... - } - if (EMPTY_MESSAGE_LINE(buf)) - searchingHeaders = PR_FALSE; - } - delete bodyHandler; - *pResult = result; - return err; -} - -nsresult nsMsgSearchTerm::MatchBody (nsIMsgSearchScopeTerm *scope, PRUint32 offset, PRUint32 length /*in lines*/, const char *folderCharset, - nsIMsgDBHdr *msg, nsIMsgDatabase* db, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - nsresult err = NS_OK; - - PRBool result = PR_FALSE; - *pResult = PR_FALSE; - - // Small hack so we don't look all through a message when someone has - // specified "BODY IS foo". ### Since length is in lines, this is not quite right. - if ((length > 0) && (m_operator == nsMsgSearchOp::Is || m_operator == nsMsgSearchOp::Isnt)) - length = PL_strlen (m_value.string); - - nsMsgBodyHandler * bodyHan = new nsMsgBodyHandler (scope, offset, length, msg, db); - if (!bodyHan) - return NS_ERROR_OUT_OF_MEMORY; - - nsCAutoString buf; - PRBool endOfFile = PR_FALSE; // if retValue == 0, we've hit the end of the file - uint32 lines = 0; - - // Change the sense of the loop so we don't bail out prematurely - // on negative terms. i.e. opDoesntContain must look at all lines - PRBool boolContinueLoop; - GetMatchAllBeforeDeciding(&boolContinueLoop); - result = boolContinueLoop; - - // If there's a '=' in the search term, then we're not going to do - // quoted printable decoding. Otherwise we assume everything is - // quoted printable. Obviously everything isn't quoted printable, but - // since we don't have a MIME parser handy, and we want to err on the - // side of too many hits rather than not enough, we'll assume in that - // general direction. Blech. ### FIX ME - // bug fix #314637: for stateful charsets like ISO-2022-JP, we don't - // want to decode quoted printable since it contains '='. - PRBool isQuotedPrintable = !nsMsgI18Nstateful_charset(folderCharset) && - (PL_strchr (m_value.string, '=') == nsnull); - - nsCString compare; - while (!endOfFile && result == boolContinueLoop) - { - if (bodyHan->GetNextLine(buf) >= 0) - { - PRBool softLineBreak = PR_FALSE; - // Do in-place decoding of quoted printable - if (isQuotedPrintable) - { - softLineBreak = StringEndsWith(buf, NS_LITERAL_CSTRING("=")); - MsgStripQuotedPrintable ((unsigned char*)buf.get()); +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Seth Spitzer + * Jungshik Shin + * David Bienvenu + * + * 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"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "msgCore.h" +#include "nsXPIDLString.h" +#include "nsReadableUtils.h" + +#include "nsMsgSearchCore.h" +#include "nsIMsgSearchSession.h" +#include "nsMsgUtils.h" +#include "nsIMsgDatabase.h" +#include "nsMsgSearchTerm.h" +#include "nsMsgSearchScopeTerm.h" +#include "nsMsgBodyHandler.h" +#include "nsMsgResultElement.h" +#include "nsIMsgImapMailFolder.h" +#include "nsMsgSearchImap.h" +#include "nsMsgLocalSearch.h" +#include "nsMsgSearchNews.h" +#include "nsMsgSearchValue.h" +#include "nsMsgI18N.h" +#include "nsIMimeConverter.h" +#include "nsMsgMimeCID.h" +#include "nsTime.h" +#include "nsIPrefBranch.h" +#include "nsIPrefService.h" +#include "nsIMsgFilterPlugin.h" +#include "nsILocalFile.h" +#include "nsIRDFService.h" +#include "nsISupportsObsolete.h" +#include "nsNetCID.h" +#include "nsIFileStreams.h" +#include "nsUnicharUtils.h" +//--------------------------------------------------------------------------- +// nsMsgSearchTerm specifies one criterion, e.g. name contains phil +//--------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +//-------------------- Implementation of nsMsgSearchTerm ----------------------- +//----------------------------------------------------------------------------- +#define MAILNEWS_CUSTOM_HEADERS "mailnews.customHeaders" + +typedef struct +{ + nsMsgSearchAttribValue attrib; + const char *attribName; +} nsMsgSearchAttribEntry; + +nsMsgSearchAttribEntry SearchAttribEntryTable[] = +{ + {nsMsgSearchAttrib::Subject, "subject"}, + {nsMsgSearchAttrib::Sender, "from"}, + {nsMsgSearchAttrib::Body, "body"}, + {nsMsgSearchAttrib::Date, "date"}, + {nsMsgSearchAttrib::Priority, "priority"}, + {nsMsgSearchAttrib::MsgStatus, "status"}, + {nsMsgSearchAttrib::To, "to"}, + {nsMsgSearchAttrib::CC, "cc"}, + {nsMsgSearchAttrib::ToOrCC, "to or cc"}, + {nsMsgSearchAttrib::AgeInDays, "age in days"}, + {nsMsgSearchAttrib::Label, "label"}, + {nsMsgSearchAttrib::Keywords, "tag"}, + {nsMsgSearchAttrib::Size, "size"}, + // this used to be nsMsgSearchAttrib::SenderInAddressBook + // we used to have two Sender menuitems + // for backward compatability, we can still parse + // the old style. see bug #179803 + {nsMsgSearchAttrib::Sender, "from in ab"}, + {nsMsgSearchAttrib::JunkStatus, "junk status"}, + {nsMsgSearchAttrib::HasAttachmentStatus, "has attachment status"}, +}; + +// Take a string which starts off with an attribute +// return the matching attribute. If the string is not in the table, then we can conclude that it is an arbitrary header +nsresult NS_MsgGetAttributeFromString(const char *string, PRInt16 *attrib) +{ + NS_ENSURE_ARG_POINTER(string); + NS_ENSURE_ARG_POINTER(attrib); + + PRBool found = PR_FALSE; + for (int idxAttrib = 0; idxAttrib < (int)(sizeof(SearchAttribEntryTable) / sizeof(nsMsgSearchAttribEntry)); idxAttrib++) + { + if (!PL_strcasecmp(string, SearchAttribEntryTable[idxAttrib].attribName)) + { + found = PR_TRUE; + *attrib = SearchAttribEntryTable[idxAttrib].attrib; + break; + } + } + if (!found) + { + nsresult rv; + PRBool goodHdr; + IsRFC822HeaderFieldName(string, &goodHdr); + if (!goodHdr) + return NS_MSG_INVALID_CUSTOM_HEADER; + //49 is for showing customize... in ui, headers start from 50 onwards up until 99. + *attrib = nsMsgSearchAttrib::OtherHeader+1; + + nsCOMPtr prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr prefBranch; + rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch)); + NS_ENSURE_SUCCESS(rv, rv); + + nsXPIDLCString headers; + prefBranch->GetCharPref(MAILNEWS_CUSTOM_HEADERS, getter_Copies(headers)); + + if (!headers.IsEmpty()) + { + char *headersString = ToNewCString(headers); + + nsCAutoString hdrStr; + hdrStr.Adopt(headersString); + hdrStr.StripWhitespace(); //remove whitespace before parsing + + char *newStr=nsnull; + char *token = nsCRT::strtok(headersString,":", &newStr); + PRUint32 i=0; + while (token) + { + if (nsCRT::strcasecmp(token, string) == 0) + { + *attrib += i; //we found custom header in the pref + found = PR_TRUE; + break; + } + token = nsCRT::strtok(newStr,":", &newStr); + i++; + } + } + } + // If we didn't find the header in MAILNEWS_CUSTOM_HEADERS, we're + // going to return NS_OK and an attrib of nsMsgSearchAttrib::OtherHeader+1. + // in case it's a client side spam filter description filter, + // which doesn't add its headers to mailnews.customMailHeaders. + // We've already checked that it's a valid header and returned + // an error if so. + + return NS_OK; +} + +nsresult NS_MsgGetStringForAttribute(PRInt16 attrib, const char **string) +{ + NS_ENSURE_ARG_POINTER(string); + + PRBool found = PR_FALSE; + for (int idxAttrib = 0; idxAttrib < (int)(sizeof(SearchAttribEntryTable) / sizeof(nsMsgSearchAttribEntry)); idxAttrib++) + { + // I'm using the idx's as aliases into MSG_SearchAttribute and + // MSG_SearchOperator enums which is legal because of the way the + // enums are defined (starts at 0, numItems at end) + if (attrib == SearchAttribEntryTable[idxAttrib].attrib) + { + found = PR_TRUE; + *string = SearchAttribEntryTable[idxAttrib].attribName; + break; + } + } + // we no longer return invalid attribute. If we cannot find the string in the table, + // then it is an arbitrary header. Return success regardless if found or not + return NS_OK; +} + +typedef struct +{ + nsMsgSearchOpValue op; + const char *opName; +} nsMsgSearchOperatorEntry; + +nsMsgSearchOperatorEntry SearchOperatorEntryTable[] = +{ + {nsMsgSearchOp::Contains, "contains"}, + {nsMsgSearchOp::DoesntContain,"doesn't contain"}, + {nsMsgSearchOp::Is,"is"}, + {nsMsgSearchOp::Isnt, "isn't"}, + {nsMsgSearchOp::IsEmpty, "is empty"}, + {nsMsgSearchOp::IsBefore, "is before"}, + {nsMsgSearchOp::IsAfter, "is after"}, + {nsMsgSearchOp::IsHigherThan, "is higher than"}, + {nsMsgSearchOp::IsLowerThan, "is lower than"}, + {nsMsgSearchOp::BeginsWith, "begins with"}, + {nsMsgSearchOp::EndsWith, "ends with"}, + {nsMsgSearchOp::IsInAB, "is in ab"}, + {nsMsgSearchOp::IsntInAB, "isn't in ab"}, + {nsMsgSearchOp::IsGreaterThan, "is greater than"}, + {nsMsgSearchOp::IsLessThan, "is less than"} +}; + +nsresult NS_MsgGetOperatorFromString(const char *string, PRInt16 *op) +{ + NS_ENSURE_ARG_POINTER(string); + NS_ENSURE_ARG_POINTER(op); + + PRBool found = PR_FALSE; + for (unsigned int idxOp = 0; idxOp < sizeof(SearchOperatorEntryTable) / sizeof(nsMsgSearchOperatorEntry); idxOp++) + { + // I'm using the idx's as aliases into MSG_SearchAttribute and + // MSG_SearchOperator enums which is legal because of the way the + // enums are defined (starts at 0, numItems at end) + if (!PL_strcasecmp(string, SearchOperatorEntryTable[idxOp].opName)) + { + found = PR_TRUE; + *op = SearchOperatorEntryTable[idxOp].op; + break; + } + } + return (found) ? NS_OK : NS_ERROR_INVALID_ARG; +} + +nsresult NS_MsgGetStringForOperator(PRInt16 op, const char **string) +{ + NS_ENSURE_ARG_POINTER(string); + + PRBool found = PR_FALSE; + for (unsigned int idxOp = 0; idxOp < sizeof(SearchOperatorEntryTable) / sizeof(nsMsgSearchOperatorEntry); idxOp++) + { + // I'm using the idx's as aliases into MSG_SearchAttribute and + // MSG_SearchOperator enums which is legal because of the way the + // enums are defined (starts at 0, numItems at end) + if (op == SearchOperatorEntryTable[idxOp].op) + { + found = PR_TRUE; + *string = SearchOperatorEntryTable[idxOp].opName; + break; + } + } + + return (found) ? NS_OK : NS_ERROR_INVALID_ARG; +} + +void NS_MsgGetUntranslatedStatusName (uint32 s, nsCString *outName) +{ + const char *tmpOutName = NULL; +#define MSG_STATUS_MASK (MSG_FLAG_READ | MSG_FLAG_REPLIED | MSG_FLAG_FORWARDED | MSG_FLAG_NEW | MSG_FLAG_MARKED) + PRUint32 maskOut = (s & MSG_STATUS_MASK); + + // diddle the flags to pay attention to the most important ones first, if multiple + // flags are set. Should remove this code from the winfe. + if (maskOut & MSG_FLAG_NEW) + maskOut = MSG_FLAG_NEW; + if ( maskOut & MSG_FLAG_REPLIED && + maskOut & MSG_FLAG_FORWARDED ) + maskOut = MSG_FLAG_REPLIED|MSG_FLAG_FORWARDED; + else if ( maskOut & MSG_FLAG_FORWARDED ) + maskOut = MSG_FLAG_FORWARDED; + else if ( maskOut & MSG_FLAG_REPLIED ) + maskOut = MSG_FLAG_REPLIED; + + switch (maskOut) + { + case MSG_FLAG_READ: + tmpOutName = "read"; + break; + case MSG_FLAG_REPLIED: + tmpOutName = "replied"; + break; + case MSG_FLAG_FORWARDED: + tmpOutName = "forwarded"; + break; + case MSG_FLAG_FORWARDED|MSG_FLAG_REPLIED: + tmpOutName = "replied and forwarded"; + break; + case MSG_FLAG_NEW: + tmpOutName = "new"; + break; + case MSG_FLAG_MARKED: + tmpOutName = "flagged"; + break; + default: + // This is fine, status may be "unread" for example + break; + } + + if (tmpOutName) + *outName = tmpOutName; +} + + +PRInt32 NS_MsgGetStatusValueFromName(char *name) +{ + if (!strcmp("read", name)) + return MSG_FLAG_READ; + if (!strcmp("replied", name)) + return MSG_FLAG_REPLIED; + if (!strcmp("forwarded", name)) + return MSG_FLAG_FORWARDED; + if (!strcmp("replied and forwarded", name)) + return MSG_FLAG_FORWARDED|MSG_FLAG_REPLIED; + if (!strcmp("new", name)) + return MSG_FLAG_NEW; + if (!strcmp("flagged", name)) + return MSG_FLAG_MARKED; + return 0; +} + + +// Needed for DeStream method. +nsMsgSearchTerm::nsMsgSearchTerm() +{ + // initialize this to zero + m_value.string=nsnull; + m_value.attribute=0; + m_value.u.priority=0; + m_attribute = nsMsgSearchAttrib::Default; + mBeginsGrouping = PR_FALSE; + mEndsGrouping = PR_FALSE; + m_matchAll = PR_FALSE; +} + +nsMsgSearchTerm::nsMsgSearchTerm ( + nsMsgSearchAttribValue attrib, + nsMsgSearchOpValue op, + nsIMsgSearchValue *val, + nsMsgSearchBooleanOperator boolOp, + const char * arbitraryHeader) +{ + m_operator = op; + m_attribute = attrib; + m_booleanOp = boolOp; + if (attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes && arbitraryHeader) + m_arbitraryHeader = arbitraryHeader; + nsMsgResultElement::AssignValues (val, &m_value); + m_matchAll = PR_FALSE; +} + + + +nsMsgSearchTerm::~nsMsgSearchTerm () +{ + if (IS_STRING_ATTRIBUTE (m_attribute) && m_value.string) + Recycle(m_value.string); +} + +NS_IMPL_ISUPPORTS1(nsMsgSearchTerm, nsIMsgSearchTerm) + + +// Perhaps we could find a better place for this? +// Caller needs to free. +/* static */char *nsMsgSearchTerm::EscapeQuotesInStr(const char *str) +{ + int numQuotes = 0; + for (const char *strPtr = str; *strPtr; strPtr++) + if (*strPtr == '"') + numQuotes++; + int escapedStrLen = PL_strlen(str) + numQuotes; + char *escapedStr = (char *) PR_Malloc(escapedStrLen + 1); + if (escapedStr) + { + char *destPtr; + for (destPtr = escapedStr; *str; str++) + { + if (*str == '"') + *destPtr++ = '\\'; + *destPtr++ = *str; + } + *destPtr = '\0'; + } + return escapedStr; +} + + +nsresult nsMsgSearchTerm::OutputValue(nsCString &outputStr) +{ + if (IS_STRING_ATTRIBUTE(m_attribute) && m_value.string) + { + PRBool quoteVal = PR_FALSE; + // need to quote strings with ')' and strings starting with '"' or ' ' + // filter code will escape quotes + if (PL_strchr(m_value.string, ')') || + (m_value.string[0] == ' ') || + (m_value.string[0] == '"')) + { + quoteVal = PR_TRUE; + outputStr += "\""; + } + if (PL_strchr(m_value.string, '"')) + { + char *escapedString = nsMsgSearchTerm::EscapeQuotesInStr(m_value.string); + if (escapedString) + { + outputStr += escapedString; + PR_Free(escapedString); + } + + } + else + { + outputStr += m_value.string; + } + if (quoteVal) + outputStr += "\""; + } + else + { + switch (m_attribute) + { + case nsMsgSearchAttrib::Date: + { + PRExplodedTime exploded; + PR_ExplodeTime(m_value.u.date, PR_LocalTimeParameters, &exploded); + + // wow, so tm_mon is 0 based, tm_mday is 1 based. + char dateBuf[100]; + PR_FormatTimeUSEnglish (dateBuf, sizeof(dateBuf), "%d-%b-%Y", &exploded); + outputStr += dateBuf; + break; + } + case nsMsgSearchAttrib::AgeInDays: + { + outputStr.AppendInt(m_value.u.age); + break; + } + case nsMsgSearchAttrib::Label: + { + outputStr.AppendInt(m_value.u.label); + break; + } + case nsMsgSearchAttrib::JunkStatus: + { + outputStr.AppendInt(m_value.u.junkStatus); // only if we write to disk, right? + break; + } + case nsMsgSearchAttrib::MsgStatus: + { + nsCAutoString status; + NS_MsgGetUntranslatedStatusName (m_value.u.msgStatus, &status); + outputStr += status; + break; + } + case nsMsgSearchAttrib::Priority: + { + nsCAutoString priority; + NS_MsgGetUntranslatedPriorityName(m_value.u.priority, priority); + outputStr += priority; + break; + } + case nsMsgSearchAttrib::HasAttachmentStatus: + { + outputStr.Append("true"); // don't need anything here, really + break; + } + case nsMsgSearchAttrib::Size: + { + outputStr.AppendInt(m_value.u.size); + break; + } + default: + NS_ASSERTION(PR_FALSE, "trying to output invalid attribute"); + break; + } + } + return NS_OK; +} + +NS_IMETHODIMP nsMsgSearchTerm::GetTermAsString (nsACString &outStream) +{ + const char *attrib, *operatorStr; + nsCAutoString outputStr; + nsresult ret; + + if (m_matchAll) + { + outStream = "ALL"; + return NS_OK; + } + ret = NS_MsgGetStringForAttribute(m_attribute, &attrib); + if (ret != NS_OK) + return ret; + + if (m_attribute > nsMsgSearchAttrib::OtherHeader && m_attribute < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if arbitrary header, use it instead! + { + outputStr = "\""; + outputStr += m_arbitraryHeader; + outputStr += "\""; + } + else + outputStr = attrib; + + outputStr += ','; + + ret = NS_MsgGetStringForOperator(m_operator, &operatorStr); + if (ret != NS_OK) + return ret; + + outputStr += operatorStr; + outputStr += ','; + + OutputValue(outputStr); + outStream = outputStr; + return NS_OK; +} + +// fill in m_value from the input stream. +nsresult nsMsgSearchTerm::ParseValue(char *inStream) +{ + if (IS_STRING_ATTRIBUTE(m_attribute)) + { + PRBool quoteVal = PR_FALSE; + while (nsCRT::IsAsciiSpace(*inStream)) + inStream++; + // need to remove pair of '"', if present + if (*inStream == '"') + { + quoteVal = PR_TRUE; + inStream++; + } + int valueLen = PL_strlen(inStream); + if (quoteVal && inStream[valueLen - 1] == '"') + valueLen--; + + m_value.string = (char *) PR_Malloc(valueLen + 1); + PL_strncpy(m_value.string, inStream, valueLen + 1); + m_value.string[valueLen] = '\0'; + } + else + { + switch (m_attribute) + { + case nsMsgSearchAttrib::Date: + PR_ParseTimeString (inStream, PR_FALSE, &m_value.u.date); + break; + case nsMsgSearchAttrib::MsgStatus: + m_value.u.msgStatus = NS_MsgGetStatusValueFromName(inStream); + break; + case nsMsgSearchAttrib::Priority: + NS_MsgGetPriorityFromString(inStream, m_value.u.priority); + break; + case nsMsgSearchAttrib::AgeInDays: + m_value.u.age = atoi(inStream); + break; + case nsMsgSearchAttrib::Label: + m_value.u.label = atoi(inStream); + break; + case nsMsgSearchAttrib::JunkStatus: + m_value.u.junkStatus = atoi(inStream); // only if we read from disk, right? + break; + case nsMsgSearchAttrib::HasAttachmentStatus: + m_value.u.msgStatus = MSG_FLAG_ATTACHMENT; + break; // this should always be true. + case nsMsgSearchAttrib::Size: + m_value.u.size = atoi(inStream); + break; + default: + NS_ASSERTION(PR_FALSE, "invalid attribute parsing search term value"); + break; + } + } + m_value.attribute = m_attribute; + return NS_OK; +} + +// find the operator code for this operator string. +nsresult +nsMsgSearchTerm::ParseOperator(char *inStream, nsMsgSearchOpValue *value) +{ + NS_ENSURE_ARG_POINTER(value); + PRInt16 operatorVal; + while (nsCRT::IsAsciiSpace(*inStream)) + inStream++; + + char *commaSep = PL_strchr(inStream, ','); + + if (commaSep) + *commaSep = '\0'; + + nsresult err = NS_MsgGetOperatorFromString(inStream, &operatorVal); + *value = (nsMsgSearchOpValue) operatorVal; + return err; +} + +// find the attribute code for this comma-delimited attribute. +nsresult +nsMsgSearchTerm::ParseAttribute(char *inStream, nsMsgSearchAttribValue *attrib) +{ + while (nsCRT::IsAsciiSpace(*inStream)) + inStream++; + + // if we are dealing with an arbitrary header, it may be quoted.... + PRBool quoteVal = PR_FALSE; + if (*inStream == '"') + { + quoteVal = PR_TRUE; + inStream++; + } + + // arbitrary headers are quoted + char *separator = strchr(inStream, quoteVal ? '"' : ','); + + if (separator) + *separator = '\0'; + + PRInt16 attributeVal; + nsresult rv = NS_MsgGetAttributeFromString(inStream, &attributeVal); + NS_ENSURE_SUCCESS(rv, rv); + + *attrib = (nsMsgSearchAttribValue) attributeVal; + + if (*attrib > nsMsgSearchAttrib::OtherHeader && *attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if we are dealing with an arbitrary header.... + m_arbitraryHeader = inStream; + + return rv; +} + +// De stream one search term. If the condition looks like +// condition = "(to or cc, contains, r-thompson) AND (body, doesn't contain, fred)" +// This routine should get called twice, the first time +// with "to or cc, contains, r-thompson", the second time with +// "body, doesn't contain, fred" + +nsresult nsMsgSearchTerm::DeStreamNew (char *inStream, PRInt16 /*length*/) +{ + if (!strcmp(inStream, "ALL")) + { + m_matchAll = PR_TRUE; + return NS_OK; + } + char *commaSep = PL_strchr(inStream, ','); + nsresult rv = ParseAttribute(inStream, &m_attribute); // will allocate space for arbitrary header if necessary + NS_ENSURE_SUCCESS(rv, rv); + if (!commaSep) + return NS_ERROR_INVALID_ARG; + char *secondCommaSep = PL_strchr(commaSep + 1, ','); + if (commaSep) + rv = ParseOperator(commaSep + 1, &m_operator); + NS_ENSURE_SUCCESS(rv, rv); + // convert label filters and saved searches to keyword equivalents + if (secondCommaSep) + ParseValue(secondCommaSep + 1); + if (m_attribute == nsMsgSearchAttrib::Label) + { + nsCAutoString keyword("$label"); + m_value.attribute = m_attribute = nsMsgSearchAttrib::Keywords; + keyword.Append('0' + m_value.u.label); + m_value.string = PL_strdup(keyword.get()); + } + return NS_OK; +} + + +// Looks in the MessageDB for the user specified arbitrary header, if it finds the header, it then looks for a match against +// the value for the header. +nsresult nsMsgSearchTerm::MatchArbitraryHeader (nsIMsgSearchScopeTerm *scope, + PRUint32 offset, + PRUint32 length /* in lines*/, + const char *charset, + PRBool charsetOverride, + nsIMsgDBHdr *msg, + nsIMsgDatabase* db, + const char * headers, + PRUint32 headersSize, + PRBool ForFiltering, + PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + *pResult = PR_FALSE; + nsresult err = NS_OK; + PRBool result; + + nsMsgBodyHandler * bodyHandler = new nsMsgBodyHandler (scope, offset,length, msg, db, headers, headersSize, ForFiltering); + if (!bodyHandler) + return NS_ERROR_OUT_OF_MEMORY; + + bodyHandler->SetStripHeaders (PR_FALSE); + + GetMatchAllBeforeDeciding(&result); + + nsCAutoString buf; + nsCAutoString curMsgHeader; + PRBool searchingHeaders = PR_TRUE; + while (searchingHeaders && (bodyHandler->GetNextLine(buf) >=0)) + { + char * buf_end = (char *) (buf.get() + buf.Length()); + int headerLength = m_arbitraryHeader.Length(); + PRBool isContinuationHeader = NS_IsAsciiWhitespace(buf.CharAt(0)); + // this handles wrapped header lines, which start with whitespace. + // If the line starts with whitespace, then we use the current header. + if (!isContinuationHeader) + { + PRUint32 colonPos = buf.FindChar(':'); + buf.Left(curMsgHeader, colonPos); + } + + if (curMsgHeader.Equals(m_arbitraryHeader, nsCaseInsensitiveCStringComparator())) + { + // value occurs after the header name or whitespace continuation char. + const char * headerValue = buf.get() + (isContinuationHeader ? 1 : headerLength); + if (headerValue < buf_end && headerValue[0] == ':') // + 1 to account for the colon which is MANDATORY + headerValue++; + + // strip leading white space + while (headerValue < buf_end && nsCRT::IsAsciiSpace(*headerValue)) + headerValue++; // advance to next character + + // strip trailing white space + char * end = buf_end - 1; + while (end > headerValue && nsCRT::IsAsciiSpace(*end)) // while we haven't gone back past the start and we are white space.... + { + *end = '\0'; // eat up the white space + end--; // move back and examine the previous character.... + } + + if (headerValue < buf_end && *headerValue) // make sure buf has info besides just the header + { + PRBool result2; + err = MatchRfc2047String(headerValue, charset, charsetOverride, &result2); // match value with the other info... + if (result != result2) // if we found a match + { + searchingHeaders = PR_FALSE; // then stop examining the headers + result = result2; + } + } + else + NS_ASSERTION(PR_FALSE, "error matching arbitrary headers"); // mscott --> i'd be curious if there is a case where this fails.... + } + if (EMPTY_MESSAGE_LINE(buf)) + searchingHeaders = PR_FALSE; + } + delete bodyHandler; + *pResult = result; + return err; +} + +nsresult nsMsgSearchTerm::MatchBody (nsIMsgSearchScopeTerm *scope, PRUint32 offset, PRUint32 length /*in lines*/, const char *folderCharset, + nsIMsgDBHdr *msg, nsIMsgDatabase* db, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + nsresult err = NS_OK; + + PRBool result = PR_FALSE; + *pResult = PR_FALSE; + + // Small hack so we don't look all through a message when someone has + // specified "BODY IS foo". ### Since length is in lines, this is not quite right. + if ((length > 0) && (m_operator == nsMsgSearchOp::Is || m_operator == nsMsgSearchOp::Isnt)) + length = PL_strlen (m_value.string); + + nsMsgBodyHandler * bodyHan = new nsMsgBodyHandler (scope, offset, length, msg, db); + if (!bodyHan) + return NS_ERROR_OUT_OF_MEMORY; + + nsCAutoString buf; + PRBool endOfFile = PR_FALSE; // if retValue == 0, we've hit the end of the file + uint32 lines = 0; + + // Change the sense of the loop so we don't bail out prematurely + // on negative terms. i.e. opDoesntContain must look at all lines + PRBool boolContinueLoop; + GetMatchAllBeforeDeciding(&boolContinueLoop); + result = boolContinueLoop; + + // If there's a '=' in the search term, then we're not going to do + // quoted printable decoding. Otherwise we assume everything is + // quoted printable. Obviously everything isn't quoted printable, but + // since we don't have a MIME parser handy, and we want to err on the + // side of too many hits rather than not enough, we'll assume in that + // general direction. Blech. ### FIX ME + // bug fix #314637: for stateful charsets like ISO-2022-JP, we don't + // want to decode quoted printable since it contains '='. + PRBool isQuotedPrintable = !nsMsgI18Nstateful_charset(folderCharset) && + (PL_strchr (m_value.string, '=') == nsnull); + + nsCString compare; + while (!endOfFile && result == boolContinueLoop) + { + if (bodyHan->GetNextLine(buf) >= 0) + { + PRBool softLineBreak = PR_FALSE; + // Do in-place decoding of quoted printable + if (isQuotedPrintable) + { + softLineBreak = StringEndsWith(buf, NS_LITERAL_CSTRING("=")); + MsgStripQuotedPrintable ((unsigned char*)buf.get()); // in case the string shrunk, reset the length. If soft line break, // chop off the last char as well. buf.SetLength(strlen(buf.get()) - (softLineBreak ? 1 : 0)); - } - compare.Append(buf); - // If this line ends with a soft line break, loop around - // and get the next line before looking for the search string. - // This assumes the message can't end on a QP soft-line break. - // That seems like a pretty safe assumption. - if (softLineBreak) - continue; - if (!compare.IsEmpty()) - { - char startChar = (char) compare.CharAt(0); - if (startChar != nsCRT::CR && startChar != nsCRT::LF) - { - err = MatchString (compare.get(), folderCharset, &result); - lines++; - } - compare.Truncate(); - } - } - else - endOfFile = PR_TRUE; - } -#ifdef DO_I18N - if(conv) - INTL_DestroyCharCodeConverter(conv); -#endif - delete bodyHan; - *pResult = result; - return err; -} - -nsresult nsMsgSearchTerm::InitializeAddressBook() -{ - // the search attribute value has the URI for the address book we need to load. - // we need both the database and the directory. - nsresult rv = NS_OK; - - if (mDirectory) - { - nsXPIDLCString dirURI; - mDirectory->GetDirUri(getter_Copies(dirURI)); - if (strcmp(dirURI.get(), m_value.string)) - mDirectory = nsnull; // clear out the directory....we are no longer pointing to the right one - } - if (!mDirectory) - { - nsCOMPtr rdfService = do_GetService("@mozilla.org/rdf/rdf-service;1",&rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr resource; - rv = rdfService->GetResource(nsDependentCString(m_value.string), getter_AddRefs(resource)); - NS_ENSURE_SUCCESS(rv, rv); - - mDirectory = do_QueryInterface(resource, &rv); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; -} - -nsresult nsMsgSearchTerm::MatchInAddressBook(const char * aAddress, PRBool *pResult) -{ - nsresult rv = InitializeAddressBook(); - *pResult = PR_FALSE; - - // Some junkmails have empty From: fields. - if (aAddress == NULL || strlen(aAddress) == 0) - return rv; - - if (mDirectory) - { - PRBool cardExists = PR_FALSE; - rv = mDirectory->HasCardForEmailAddress(aAddress, &cardExists); - if ( (m_operator == nsMsgSearchOp::IsInAB && cardExists) || (m_operator == nsMsgSearchOp::IsntInAB && !cardExists)) - *pResult = PR_TRUE; - } - - return rv; -} - -// *pResult is PR_FALSE when strings don't match, PR_TRUE if they do. -nsresult nsMsgSearchTerm::MatchRfc2047String (const char *rfc2047string, - const char *charset, - PRBool charsetOverride, - PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - NS_ENSURE_ARG_POINTER(rfc2047string); - - nsCOMPtr mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID); - char *stringToMatch = 0; - nsresult res = mimeConverter->DecodeMimeHeader(rfc2047string, - &stringToMatch, - charset, charsetOverride, - PR_FALSE); - - if (m_attribute == nsMsgSearchAttrib::Sender && - (m_operator == nsMsgSearchOp::IsInAB || - m_operator == nsMsgSearchOp::IsntInAB)) - { - res = MatchInAddressBook(stringToMatch ? stringToMatch : rfc2047string, pResult); - } - else - res = MatchString(stringToMatch ? stringToMatch : rfc2047string, - nsnull, pResult); - - PR_Free(stringToMatch); - - return res; -} - -// *pResult is PR_FALSE when strings don't match, PR_TRUE if they do. -nsresult nsMsgSearchTerm::MatchString (const char *stringToMatch, - const char *charset, - PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - PRBool result = PR_FALSE; - - nsresult err = NS_OK; - nsAutoString utf16StrToMatch; - nsAutoString needle; - - // Save some performance for opIsEmpty - if(nsMsgSearchOp::IsEmpty != m_operator) - { - NS_ASSERTION(IsUTF8(nsDependentCString(m_value.string)), - "m_value.string is not UTF-8"); - CopyUTF8toUTF16(m_value.string, needle); - - if (charset != nsnull) - { - 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 (CaseInsensitiveFindInReadable(needle, utf16StrToMatch)) - result = PR_TRUE; - break; - case nsMsgSearchOp::DoesntContain: - if(!CaseInsensitiveFindInReadable(needle, utf16StrToMatch)) - result = PR_TRUE; - break; - case nsMsgSearchOp::Is: - if(needle.Equals(utf16StrToMatch, nsCaseInsensitiveStringComparator())) - result = PR_TRUE; - break; - case nsMsgSearchOp::Isnt: - if(!needle.Equals(utf16StrToMatch, nsCaseInsensitiveStringComparator())) - result = PR_TRUE; - break; - case nsMsgSearchOp::IsEmpty: - // For IsEmpty, we didn't copy stringToMatch to utf16StrToMatch. - if (!PL_strlen(stringToMatch)) - result = PR_TRUE; - break; - case nsMsgSearchOp::BeginsWith: - if (StringBeginsWith(utf16StrToMatch, needle, - nsCaseInsensitiveStringComparator())) - result = PR_TRUE; - break; - case nsMsgSearchOp::EndsWith: - if (StringEndsWith(utf16StrToMatch, needle, - nsCaseInsensitiveStringComparator())) - result = PR_TRUE; - break; - default: - NS_ASSERTION(PR_FALSE, "invalid operator matching search results"); - } - - *pResult = result; - return err; -} - -NS_IMETHODIMP nsMsgSearchTerm::GetMatchAllBeforeDeciding (PRBool *aResult) -{ - *aResult = (m_operator == nsMsgSearchOp::DoesntContain || m_operator == nsMsgSearchOp::Isnt); - return NS_OK; -} - - nsresult nsMsgSearchTerm::MatchRfc822String (const char *string, const char *charset, PRBool charsetOverride, PRBool *pResult) - { - NS_ENSURE_ARG_POINTER(pResult); - *pResult = PR_FALSE; - PRBool result; - nsresult err = InitHeaderAddressParser(); - if (NS_FAILED(err)) - return err; - // Isolate the RFC 822 parsing weirdnesses here. MSG_ParseRFC822Addresses - // returns a catenated string of null-terminated strings, which we walk - // across, tring to match the target string to either the name OR the address - - char *names = nsnull, *addresses = nsnull; - - // Change the sense of the loop so we don't bail out prematurely - // on negative terms. i.e. opDoesntContain must look at all recipients - PRBool boolContinueLoop; - GetMatchAllBeforeDeciding(&boolContinueLoop); - result = boolContinueLoop; - - PRUint32 count; - nsresult parseErr = m_headerAddressParser->ParseHeaderAddresses(charset, string, &names, &addresses, &count) ; - - if (NS_SUCCEEDED(parseErr) && count > 0) - { - NS_ASSERTION(names, "couldn't get names"); - NS_ASSERTION(addresses, "couldn't get addresses"); - if (!names || !addresses) - return err; - - nsCAutoString walkNames; - nsCAutoString walkAddresses; - PRInt32 namePos = 0; - PRInt32 addressPos = 0; - for (PRUint32 i = 0; i < count && result == boolContinueLoop; i++) - { - walkNames = names + namePos; - walkAddresses = addresses + addressPos; - if (m_attribute == nsMsgSearchAttrib::Sender && - (m_operator == nsMsgSearchOp::IsInAB || - m_operator == nsMsgSearchOp::IsntInAB)) - { - err = MatchRfc2047String (walkAddresses.get(), charset, charsetOverride, &result); - } - else - { - err = MatchRfc2047String (walkNames.get(), charset, charsetOverride, &result); - if (boolContinueLoop == result) - err = MatchRfc2047String (walkAddresses.get(), charset, charsetOverride, &result); - } - - namePos += walkNames.Length() + 1; - addressPos += walkAddresses.Length() + 1; - } - - PR_Free(names); - PR_Free(addresses); - } - *pResult = result; - return err; - } - - -nsresult nsMsgSearchTerm::GetLocalTimes (PRTime a, PRTime b, PRExplodedTime &aExploded, PRExplodedTime &bExploded) -{ - PR_ExplodeTime(a, PR_LocalTimeParameters, &aExploded); - PR_ExplodeTime(b, PR_LocalTimeParameters, &bExploded); - return NS_OK; -} - - -nsresult nsMsgSearchTerm::MatchDate (PRTime dateToMatch, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - nsresult err = NS_OK; - PRBool result = PR_FALSE; - nsTime t_date(dateToMatch); - - switch (m_operator) - { - case nsMsgSearchOp::IsBefore: - if (t_date < nsTime(m_value.u.date)) - result = PR_TRUE; - break; - case nsMsgSearchOp::IsAfter: - { - nsTime adjustedDate = nsTime(m_value.u.date); - adjustedDate += 60*60*24; // we want to be greater than the next day.... - if (t_date > adjustedDate) - result = PR_TRUE; - } - break; - case nsMsgSearchOp::Is: - { - PRExplodedTime tmToMatch, tmThis; - if (NS_OK == GetLocalTimes (dateToMatch, m_value.u.date, tmToMatch, tmThis)) - { - if (tmThis.tm_year == tmToMatch.tm_year && - tmThis.tm_month == tmToMatch.tm_month && - tmThis.tm_mday == tmToMatch.tm_mday) - result = PR_TRUE; - } - } - break; - case nsMsgSearchOp::Isnt: - { - PRExplodedTime tmToMatch, tmThis; - if (NS_OK == GetLocalTimes (dateToMatch, m_value.u.date, tmToMatch, tmThis)) - { - if (tmThis.tm_year != tmToMatch.tm_year || - tmThis.tm_month != tmToMatch.tm_month || - tmThis.tm_mday != tmToMatch.tm_mday) - result = PR_TRUE; - } - } - break; - default: - NS_ASSERTION(PR_FALSE, "invalid compare op for dates"); - } - *pResult = result; - return err; -} - - -nsresult nsMsgSearchTerm::MatchAge (PRTime msgDate, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - PRBool result = PR_FALSE; - nsresult err = NS_OK; - - PRTime now = PR_Now(); - PRTime cutOffDay; - - PRInt64 microSecondsPerSecond, secondsInDays, microSecondsInDays; - - LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC); - LL_UI2L(secondsInDays, 60 * 60 * 24 * m_value.u.age); - LL_MUL(microSecondsInDays, secondsInDays, microSecondsPerSecond); - - LL_SUB(cutOffDay, now, microSecondsInDays); // = now - term->m_value.u.age * 60 * 60 * 24; - // so now cutOffDay is the PRTime cut-off point. Any msg with a time less than that will be past the age . - - switch (m_operator) - { - case nsMsgSearchOp::IsGreaterThan: // is older than - if (LL_CMP(msgDate, <, cutOffDay)) - result = PR_TRUE; - break; - case nsMsgSearchOp::IsLessThan: // is younger than - if (LL_CMP(msgDate, >, cutOffDay)) - result = PR_TRUE; - break; - case nsMsgSearchOp::Is: - PRExplodedTime msgDateExploded; - PRExplodedTime cutOffDayExploded; - if (NS_SUCCEEDED(GetLocalTimes(msgDate, cutOffDay, msgDateExploded, cutOffDayExploded))) - { - if ((msgDateExploded.tm_mday == cutOffDayExploded.tm_mday) && - (msgDateExploded.tm_month == cutOffDayExploded.tm_month) && - (msgDateExploded.tm_year == cutOffDayExploded.tm_year)) - result = PR_TRUE; - } - break; - default: - NS_ASSERTION(PR_FALSE, "invalid compare op for msg age"); - } - *pResult = result; - return err; -} - - -nsresult nsMsgSearchTerm::MatchSize (PRUint32 sizeToMatch, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - PRBool result = PR_FALSE; - // We reduce the sizeToMatch rather than supplied size - // as then we can do an exact match on the displayed value - // which will be less confusing to the user. - PRUint32 sizeToMatchKB = sizeToMatch; - - if (sizeToMatchKB < 1024) - sizeToMatchKB = 1024; - - sizeToMatchKB /= 1024; - - switch (m_operator) - { - case nsMsgSearchOp::IsGreaterThan: - if (sizeToMatchKB > m_value.u.size) - result = PR_TRUE; - break; - case nsMsgSearchOp::IsLessThan: - if (sizeToMatchKB < m_value.u.size) - result = PR_TRUE; - break; - case nsMsgSearchOp::Is: - if (sizeToMatchKB == m_value.u.size) - result = PR_TRUE; - break; - default: - break; - } - *pResult = result; - return NS_OK; -} - -nsresult nsMsgSearchTerm::MatchJunkStatus(const char *aJunkScore, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - nsMsgJunkStatus junkStatus; - if (aJunkScore && *aJunkScore) { - // cut off set at 50. this may change - // it works for our bayesian plugin, as "0" is good, and "100" is junk - // but it might need tweaking for other plugins - if ( atoi(aJunkScore) > 50 ) { - junkStatus = nsIJunkMailPlugin::JUNK; - } else { - junkStatus = nsIJunkMailPlugin::GOOD; - } - } - else { - // the in UI, we only show "junk" or "not junk" - // unknown, or nsIJunkMailPlugin::UNCLASSIFIED is shown as not junk - // so for the search to work as expected, treat unknown as not junk - junkStatus = nsIJunkMailPlugin::GOOD; - } - - nsresult rv = NS_OK; - PRBool matches = (junkStatus == m_value.u.junkStatus); - - switch (m_operator) - { - case nsMsgSearchOp::Is: - break; - case nsMsgSearchOp::Isnt: - matches = !matches; - break; - default: - rv = NS_ERROR_FAILURE; - NS_ASSERTION(PR_FALSE, "invalid compare op for junk status"); - } - - *pResult = matches; - return rv; -} - -nsresult nsMsgSearchTerm::MatchLabel(nsMsgLabelValue aLabelValue, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - PRBool result = PR_FALSE; - switch (m_operator) - { - case nsMsgSearchOp::Is: - if (m_value.u.label == aLabelValue) - result = PR_TRUE; - break; - default: - if (m_value.u.label != aLabelValue) - result = PR_TRUE; - break; - } - - *pResult = result; - return NS_OK; -} - -nsresult nsMsgSearchTerm::MatchStatus(PRUint32 statusToMatch, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - nsresult rv = NS_OK; - PRBool matches = (statusToMatch & m_value.u.msgStatus); - - switch (m_operator) - { - case nsMsgSearchOp::Is: - break; - case nsMsgSearchOp::Isnt: - matches = !matches; - break; - default: - rv = NS_ERROR_FAILURE; - NS_ERROR("invalid compare op for msg status"); - } - - *pResult = matches; - return rv; -} - -nsresult nsMsgSearchTerm::MatchKeyword(const char *keyword, PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - nsresult rv = NS_OK; - nsCAutoString keys; - - PRBool matches = PR_FALSE; - - switch (m_operator) - { - case nsMsgSearchOp::Is: - matches = !strcmp(keyword, m_value.string); - break; - case nsMsgSearchOp::Isnt: - matches = strcmp(keyword, m_value.string); - break; - case nsMsgSearchOp::DoesntContain: - case nsMsgSearchOp::Contains: - { - const char *keywordLoc = PL_strstr(keyword, m_value.string); - const char *startOfKeyword = keyword; - PRUint32 keywordLen = strlen(m_value.string); - while (keywordLoc) - { - // if the keyword is at the beginning of the string, then it's a match if - // it is either the whole string, or is followed by a space, it's a match. - if (keywordLoc == startOfKeyword || (keywordLoc[-1] == ' ')) - { - matches = keywordLen == strlen(keywordLoc) || (keywordLoc[keywordLen] == ' '); - if (matches) - break; - } - startOfKeyword = keywordLoc + keywordLen; - keywordLoc = PL_strstr(keyword, keywordLoc + keywordLen + 1); - } - } - break; - default: - rv = NS_ERROR_FAILURE; - NS_ERROR("invalid compare op for msg status"); - } - - *pResult = (m_operator == nsMsgSearchOp::DoesntContain) ? !matches : matches; - return rv; -} - -nsresult -nsMsgSearchTerm::MatchPriority (nsMsgPriorityValue priorityToMatch, - PRBool *pResult) -{ - NS_ENSURE_ARG_POINTER(pResult); - - nsresult err = NS_OK; - PRBool result=NS_OK; - - // Use this ugly little hack to get around the fact that enums don't have - // integer compare operators - int p1 = (priorityToMatch == nsMsgPriority::none) ? (int) nsMsgPriority::normal : (int) priorityToMatch; - int p2 = (int) m_value.u.priority; - - switch (m_operator) - { - case nsMsgSearchOp::IsHigherThan: - if (p1 > p2) - result = PR_TRUE; - break; - case nsMsgSearchOp::IsLowerThan: - if (p1 < p2) - result = PR_TRUE; - break; - case nsMsgSearchOp::Is: - if (p1 == p2) - result = PR_TRUE; - break; - default: - result = PR_FALSE; - err = NS_ERROR_FAILURE; - NS_ASSERTION(PR_FALSE, "invalid match operator"); - } - *pResult = result; - return err; -} - -// Lazily initialize the rfc822 header parser we're going to use to do -// header matching. -nsresult nsMsgSearchTerm::InitHeaderAddressParser() -{ - nsresult res = NS_OK; - - if (!m_headerAddressParser) - { - m_headerAddressParser = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID, &res); - } - return res; -} - -NS_IMPL_GETSET(nsMsgSearchTerm, Attrib, nsMsgSearchAttribValue, m_attribute) -NS_IMPL_GETSET(nsMsgSearchTerm, Op, nsMsgSearchOpValue, m_operator) -NS_IMPL_GETSET(nsMsgSearchTerm, MatchAll, PRBool, m_matchAll) - -NS_IMETHODIMP -nsMsgSearchTerm::GetValue(nsIMsgSearchValue **aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = new nsMsgSearchValueImpl(&m_value); - NS_IF_ADDREF(*aResult); - return NS_OK; -} - -NS_IMETHODIMP -nsMsgSearchTerm::SetValue(nsIMsgSearchValue* aValue) -{ - nsMsgResultElement::AssignValues (aValue, &m_value); - return NS_OK; -} - -NS_IMETHODIMP -nsMsgSearchTerm::GetBooleanAnd(PRBool *aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = (m_booleanOp == nsMsgSearchBooleanOp::BooleanAND); - return NS_OK; -} - -NS_IMETHODIMP -nsMsgSearchTerm::SetBooleanAnd(PRBool aValue) -{ - if (aValue) - m_booleanOp = nsMsgSearchBooleanOperator(nsMsgSearchBooleanOp::BooleanAND); - else - m_booleanOp = nsMsgSearchBooleanOperator(nsMsgSearchBooleanOp::BooleanOR); - return NS_OK; -} - -NS_IMETHODIMP -nsMsgSearchTerm::GetArbitraryHeader(char* *aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = ToNewCString(m_arbitraryHeader); - return NS_OK; -} - -NS_IMETHODIMP -nsMsgSearchTerm::SetArbitraryHeader(const char* aValue) -{ - m_arbitraryHeader = aValue; - return NS_OK; -} - -NS_IMPL_GETSET(nsMsgSearchTerm, BeginsGrouping, PRBool, mEndsGrouping) -NS_IMPL_GETSET(nsMsgSearchTerm, EndsGrouping, PRBool, mEndsGrouping) - -//----------------------------------------------------------------------------- -// nsMsgSearchScopeTerm implementation -//----------------------------------------------------------------------------- -nsMsgSearchScopeTerm::nsMsgSearchScopeTerm (nsIMsgSearchSession *session, - nsMsgSearchScopeValue attribute, - nsIMsgFolder *folder) -{ - m_attribute = attribute; - m_folder = folder; - m_searchServer = PR_TRUE; - m_searchSession = do_GetWeakReference(session); -} - -nsMsgSearchScopeTerm::nsMsgSearchScopeTerm () -{ - m_searchServer = PR_TRUE; -} - -nsMsgSearchScopeTerm::~nsMsgSearchScopeTerm () -{ - if (m_inputStream) - m_inputStream->Close(); - m_inputStream = nsnull; -} - -NS_IMPL_ISUPPORTS1(nsMsgSearchScopeTerm, nsIMsgSearchScopeTerm) - -NS_IMETHODIMP -nsMsgSearchScopeTerm::GetFolder(nsIMsgFolder **aResult) -{ - NS_IF_ADDREF(*aResult = m_folder); - return NS_OK; -} - -NS_IMETHODIMP -nsMsgSearchScopeTerm::GetSearchSession(nsIMsgSearchSession** aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - nsCOMPtr searchSession = do_QueryReferent (m_searchSession); - NS_IF_ADDREF(*aResult = searchSession); - return NS_OK; -} - -NS_IMETHODIMP nsMsgSearchScopeTerm::GetMailFile(nsILocalFile **aLocalFile) -{ - NS_ENSURE_ARG_POINTER(aLocalFile); - if (!m_localFile) - { - if (!m_folder) - return NS_ERROR_NULL_POINTER; - - m_folder->GetFilePath(getter_AddRefs(m_localFile)); - } - if (m_localFile) - { - NS_ADDREF(*aLocalFile = m_localFile); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP nsMsgSearchScopeTerm::GetInputStream(nsIInputStream **aInputStream) -{ - NS_ENSURE_ARG_POINTER(aInputStream); - nsresult rv = NS_OK; - if (!m_inputStream) - { - nsCOMPtr localFile; - rv = GetMailFile(getter_AddRefs(localFile)); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - rv = fileStream->Init(localFile, PR_RDONLY, 0664, PR_FALSE); //just have to read the messages - m_inputStream = do_QueryInterface(fileStream); - - } - NS_IF_ADDREF(*aInputStream = m_inputStream); - return rv; -} - -NS_IMETHODIMP nsMsgSearchScopeTerm::SetInputStream(nsIInputStream *aInputStream) -{ - if (!aInputStream && m_inputStream) - m_inputStream->Close(); - m_inputStream = aInputStream; - return NS_OK; -} - -nsresult nsMsgSearchScopeTerm::TimeSlice (PRBool *aDone) -{ - return m_adapter->Search(aDone); -} - -nsresult nsMsgSearchScopeTerm::InitializeAdapter (nsISupportsArray *termList) -{ - if (m_adapter) - return NS_OK; - - nsresult err = NS_OK; - - switch (m_attribute) - { - case nsMsgSearchScope::onlineMail: - m_adapter = new nsMsgSearchOnlineMail (this, termList); - break; - case nsMsgSearchScope::offlineMail: - m_adapter = new nsMsgSearchOfflineMail (this, termList); - break; - case nsMsgSearchScope::newsEx: - NS_ASSERTION(PR_FALSE, "not supporting newsEx yet"); - break; - case nsMsgSearchScope::news: - m_adapter = new nsMsgSearchNews (this, termList); - break; - case nsMsgSearchScope::allSearchableGroups: - NS_ASSERTION(PR_FALSE, "not supporting allSearchableGroups yet"); - break; - case nsMsgSearchScope::LDAP: - NS_ASSERTION(PR_FALSE, "not supporting LDAP yet"); - break; - case nsMsgSearchScope::localNews: - m_adapter = new nsMsgSearchOfflineNews (this, termList); - break; - default: - NS_ASSERTION(PR_FALSE, "invalid scope"); - err = NS_ERROR_FAILURE; - } - - if (m_adapter) - err = m_adapter->ValidateTerms (); - - return err; -} - - -char *nsMsgSearchScopeTerm::GetStatusBarName () -{ - return nsnull; -} - - -//----------------------------------------------------------------------------- -// nsMsgResultElement implementation -//----------------------------------------------------------------------------- - - -nsMsgResultElement::nsMsgResultElement(nsIMsgSearchAdapter *adapter) -{ - NS_NewISupportsArray(getter_AddRefs(m_valueList)); - m_adapter = adapter; -} - - -nsMsgResultElement::~nsMsgResultElement () -{ -} - - -nsresult nsMsgResultElement::AddValue (nsIMsgSearchValue *value) -{ - m_valueList->AppendElement (value); - return NS_OK; -} - -nsresult nsMsgResultElement::AddValue (nsMsgSearchValue *value) -{ - nsMsgSearchValueImpl* valueImpl = new nsMsgSearchValueImpl(value); - delete value; // we keep the nsIMsgSearchValue, not - // the nsMsgSearchValue - return AddValue(valueImpl); -} - - -nsresult nsMsgResultElement::AssignValues (nsIMsgSearchValue *src, nsMsgSearchValue *dst) -{ - NS_ENSURE_ARG_POINTER(src); - NS_ENSURE_ARG_POINTER(dst); - - // Yes, this could be an operator overload, but nsMsgSearchValue is totally public, so I'd - // have to define a derived class with nothing by operator=, and that seems like a bit much - nsresult err = NS_OK; - src->GetAttrib(&dst->attribute); - switch (dst->attribute) - { - case nsMsgSearchAttrib::Priority: - err = src->GetPriority(&dst->u.priority); - break; - case nsMsgSearchAttrib::Date: - err = src->GetDate(&dst->u.date); - break; - case nsMsgSearchAttrib::HasAttachmentStatus: - case nsMsgSearchAttrib::MsgStatus: - err = src->GetStatus(&dst->u.msgStatus); - break; - case nsMsgSearchAttrib::MessageKey: - err = src->GetMsgKey(&dst->u.key); - break; - case nsMsgSearchAttrib::AgeInDays: - err = src->GetAge(&dst->u.age); - break; - case nsMsgSearchAttrib::Label: - err = src->GetLabel(&dst->u.label); - break; - case nsMsgSearchAttrib::JunkStatus: - err = src->GetJunkStatus(&dst->u.junkStatus); - break; - case nsMsgSearchAttrib::Size: - err = src->GetSize(&dst->u.size); - break; - default: - if (dst->attribute < nsMsgSearchAttrib::kNumMsgSearchAttributes) - { - NS_ASSERTION(IS_STRING_ATTRIBUTE(dst->attribute), "assigning non-string result"); - nsXPIDLString unicodeString; - err = src->GetStr(getter_Copies(unicodeString)); - dst->string = ToNewUTF8String(unicodeString); - } - else - err = NS_ERROR_INVALID_ARG; - } - return err; -} - - -nsresult nsMsgResultElement::GetValue (nsMsgSearchAttribValue attrib, - nsMsgSearchValue **outValue) const -{ - nsresult err = NS_OK; - nsCOMPtr value; - *outValue = NULL; - - PRUint32 count; - m_valueList->Count(&count); - for (PRUint32 i = 0; i < count && err != NS_OK; i++) - { - m_valueList->QueryElementAt(i, NS_GET_IID(nsIMsgSearchValue), - (void **)getter_AddRefs(value)); - - nsMsgSearchAttribValue valueAttribute; - value->GetAttrib(&valueAttribute); - if (attrib == valueAttribute) - { - *outValue = new nsMsgSearchValue; - if (*outValue) - { - err = AssignValues (value, *outValue); - err = NS_OK; - } - else - err = NS_ERROR_OUT_OF_MEMORY; - } - } - return err; -} - -nsresult nsMsgResultElement::GetPrettyName (nsMsgSearchValue **value) -{ - return GetValue (nsMsgSearchAttrib::Location, value); -} - -nsresult nsMsgResultElement::Open (void *window) -{ - return NS_ERROR_NULL_POINTER; -} - - + } + compare.Append(buf); + // If this line ends with a soft line break, loop around + // and get the next line before looking for the search string. + // This assumes the message can't end on a QP soft-line break. + // That seems like a pretty safe assumption. + if (softLineBreak) + continue; + if (!compare.IsEmpty()) + { + char startChar = (char) compare.CharAt(0); + if (startChar != nsCRT::CR && startChar != nsCRT::LF) + { + err = MatchString (compare.get(), folderCharset, &result); + lines++; + } + compare.Truncate(); + } + } + else + endOfFile = PR_TRUE; + } +#ifdef DO_I18N + if(conv) + INTL_DestroyCharCodeConverter(conv); +#endif + delete bodyHan; + *pResult = result; + return err; +} + +nsresult nsMsgSearchTerm::InitializeAddressBook() +{ + // the search attribute value has the URI for the address book we need to load. + // we need both the database and the directory. + nsresult rv = NS_OK; + + if (mDirectory) + { + nsXPIDLCString dirURI; + mDirectory->GetDirUri(getter_Copies(dirURI)); + if (strcmp(dirURI.get(), m_value.string)) + mDirectory = nsnull; // clear out the directory....we are no longer pointing to the right one + } + if (!mDirectory) + { + nsCOMPtr rdfService = do_GetService("@mozilla.org/rdf/rdf-service;1",&rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr resource; + rv = rdfService->GetResource(nsDependentCString(m_value.string), getter_AddRefs(resource)); + NS_ENSURE_SUCCESS(rv, rv); + + mDirectory = do_QueryInterface(resource, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + + return NS_OK; +} + +nsresult nsMsgSearchTerm::MatchInAddressBook(const char * aAddress, PRBool *pResult) +{ + nsresult rv = InitializeAddressBook(); + *pResult = PR_FALSE; + + // Some junkmails have empty From: fields. + if (aAddress == NULL || strlen(aAddress) == 0) + return rv; + + if (mDirectory) + { + PRBool cardExists = PR_FALSE; + rv = mDirectory->HasCardForEmailAddress(aAddress, &cardExists); + if ( (m_operator == nsMsgSearchOp::IsInAB && cardExists) || (m_operator == nsMsgSearchOp::IsntInAB && !cardExists)) + *pResult = PR_TRUE; + } + + return rv; +} + +// *pResult is PR_FALSE when strings don't match, PR_TRUE if they do. +nsresult nsMsgSearchTerm::MatchRfc2047String (const char *rfc2047string, + const char *charset, + PRBool charsetOverride, + PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + NS_ENSURE_ARG_POINTER(rfc2047string); + + nsCOMPtr mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID); + char *stringToMatch = 0; + nsresult res = mimeConverter->DecodeMimeHeader(rfc2047string, + &stringToMatch, + charset, charsetOverride, + PR_FALSE); + + if (m_attribute == nsMsgSearchAttrib::Sender && + (m_operator == nsMsgSearchOp::IsInAB || + m_operator == nsMsgSearchOp::IsntInAB)) + { + res = MatchInAddressBook(stringToMatch ? stringToMatch : rfc2047string, pResult); + } + else + res = MatchString(stringToMatch ? stringToMatch : rfc2047string, + nsnull, pResult); + + PR_Free(stringToMatch); + + return res; +} + +// *pResult is PR_FALSE when strings don't match, PR_TRUE if they do. +nsresult nsMsgSearchTerm::MatchString (const char *stringToMatch, + const char *charset, + PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + PRBool result = PR_FALSE; + + nsresult err = NS_OK; + nsAutoString utf16StrToMatch; + nsAutoString needle; + + // Save some performance for opIsEmpty + if(nsMsgSearchOp::IsEmpty != m_operator) + { + NS_ASSERTION(IsUTF8(nsDependentCString(m_value.string)), + "m_value.string is not UTF-8"); + CopyUTF8toUTF16(m_value.string, needle); + + if (charset != nsnull) + { + 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 (CaseInsensitiveFindInReadable(needle, utf16StrToMatch)) + result = PR_TRUE; + break; + case nsMsgSearchOp::DoesntContain: + if(!CaseInsensitiveFindInReadable(needle, utf16StrToMatch)) + result = PR_TRUE; + break; + case nsMsgSearchOp::Is: + if(needle.Equals(utf16StrToMatch, nsCaseInsensitiveStringComparator())) + result = PR_TRUE; + break; + case nsMsgSearchOp::Isnt: + if(!needle.Equals(utf16StrToMatch, nsCaseInsensitiveStringComparator())) + result = PR_TRUE; + break; + case nsMsgSearchOp::IsEmpty: + // For IsEmpty, we didn't copy stringToMatch to utf16StrToMatch. + if (!PL_strlen(stringToMatch)) + result = PR_TRUE; + break; + case nsMsgSearchOp::BeginsWith: + if (StringBeginsWith(utf16StrToMatch, needle, + nsCaseInsensitiveStringComparator())) + result = PR_TRUE; + break; + case nsMsgSearchOp::EndsWith: + if (StringEndsWith(utf16StrToMatch, needle, + nsCaseInsensitiveStringComparator())) + result = PR_TRUE; + break; + default: + NS_ASSERTION(PR_FALSE, "invalid operator matching search results"); + } + + *pResult = result; + return err; +} + +NS_IMETHODIMP nsMsgSearchTerm::GetMatchAllBeforeDeciding (PRBool *aResult) +{ + *aResult = (m_operator == nsMsgSearchOp::DoesntContain || m_operator == nsMsgSearchOp::Isnt); + return NS_OK; +} + + nsresult nsMsgSearchTerm::MatchRfc822String (const char *string, const char *charset, PRBool charsetOverride, PRBool *pResult) + { + NS_ENSURE_ARG_POINTER(pResult); + *pResult = PR_FALSE; + PRBool result; + nsresult err = InitHeaderAddressParser(); + if (NS_FAILED(err)) + return err; + // Isolate the RFC 822 parsing weirdnesses here. MSG_ParseRFC822Addresses + // returns a catenated string of null-terminated strings, which we walk + // across, tring to match the target string to either the name OR the address + + char *names = nsnull, *addresses = nsnull; + + // Change the sense of the loop so we don't bail out prematurely + // on negative terms. i.e. opDoesntContain must look at all recipients + PRBool boolContinueLoop; + GetMatchAllBeforeDeciding(&boolContinueLoop); + result = boolContinueLoop; + + PRUint32 count; + nsresult parseErr = m_headerAddressParser->ParseHeaderAddresses(charset, string, &names, &addresses, &count) ; + + if (NS_SUCCEEDED(parseErr) && count > 0) + { + NS_ASSERTION(names, "couldn't get names"); + NS_ASSERTION(addresses, "couldn't get addresses"); + if (!names || !addresses) + return err; + + nsCAutoString walkNames; + nsCAutoString walkAddresses; + PRInt32 namePos = 0; + PRInt32 addressPos = 0; + for (PRUint32 i = 0; i < count && result == boolContinueLoop; i++) + { + walkNames = names + namePos; + walkAddresses = addresses + addressPos; + if (m_attribute == nsMsgSearchAttrib::Sender && + (m_operator == nsMsgSearchOp::IsInAB || + m_operator == nsMsgSearchOp::IsntInAB)) + { + err = MatchRfc2047String (walkAddresses.get(), charset, charsetOverride, &result); + } + else + { + err = MatchRfc2047String (walkNames.get(), charset, charsetOverride, &result); + if (boolContinueLoop == result) + err = MatchRfc2047String (walkAddresses.get(), charset, charsetOverride, &result); + } + + namePos += walkNames.Length() + 1; + addressPos += walkAddresses.Length() + 1; + } + + PR_Free(names); + PR_Free(addresses); + } + *pResult = result; + return err; + } + + +nsresult nsMsgSearchTerm::GetLocalTimes (PRTime a, PRTime b, PRExplodedTime &aExploded, PRExplodedTime &bExploded) +{ + PR_ExplodeTime(a, PR_LocalTimeParameters, &aExploded); + PR_ExplodeTime(b, PR_LocalTimeParameters, &bExploded); + return NS_OK; +} + + +nsresult nsMsgSearchTerm::MatchDate (PRTime dateToMatch, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + nsresult err = NS_OK; + PRBool result = PR_FALSE; + nsTime t_date(dateToMatch); + + switch (m_operator) + { + case nsMsgSearchOp::IsBefore: + if (t_date < nsTime(m_value.u.date)) + result = PR_TRUE; + break; + case nsMsgSearchOp::IsAfter: + { + nsTime adjustedDate = nsTime(m_value.u.date); + adjustedDate += 60*60*24; // we want to be greater than the next day.... + if (t_date > adjustedDate) + result = PR_TRUE; + } + break; + case nsMsgSearchOp::Is: + { + PRExplodedTime tmToMatch, tmThis; + if (NS_OK == GetLocalTimes (dateToMatch, m_value.u.date, tmToMatch, tmThis)) + { + if (tmThis.tm_year == tmToMatch.tm_year && + tmThis.tm_month == tmToMatch.tm_month && + tmThis.tm_mday == tmToMatch.tm_mday) + result = PR_TRUE; + } + } + break; + case nsMsgSearchOp::Isnt: + { + PRExplodedTime tmToMatch, tmThis; + if (NS_OK == GetLocalTimes (dateToMatch, m_value.u.date, tmToMatch, tmThis)) + { + if (tmThis.tm_year != tmToMatch.tm_year || + tmThis.tm_month != tmToMatch.tm_month || + tmThis.tm_mday != tmToMatch.tm_mday) + result = PR_TRUE; + } + } + break; + default: + NS_ASSERTION(PR_FALSE, "invalid compare op for dates"); + } + *pResult = result; + return err; +} + + +nsresult nsMsgSearchTerm::MatchAge (PRTime msgDate, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + PRBool result = PR_FALSE; + nsresult err = NS_OK; + + PRTime now = PR_Now(); + PRTime cutOffDay; + + PRInt64 microSecondsPerSecond, secondsInDays, microSecondsInDays; + + LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC); + LL_UI2L(secondsInDays, 60 * 60 * 24 * m_value.u.age); + LL_MUL(microSecondsInDays, secondsInDays, microSecondsPerSecond); + + LL_SUB(cutOffDay, now, microSecondsInDays); // = now - term->m_value.u.age * 60 * 60 * 24; + // so now cutOffDay is the PRTime cut-off point. Any msg with a time less than that will be past the age . + + switch (m_operator) + { + case nsMsgSearchOp::IsGreaterThan: // is older than + if (LL_CMP(msgDate, <, cutOffDay)) + result = PR_TRUE; + break; + case nsMsgSearchOp::IsLessThan: // is younger than + if (LL_CMP(msgDate, >, cutOffDay)) + result = PR_TRUE; + break; + case nsMsgSearchOp::Is: + PRExplodedTime msgDateExploded; + PRExplodedTime cutOffDayExploded; + if (NS_SUCCEEDED(GetLocalTimes(msgDate, cutOffDay, msgDateExploded, cutOffDayExploded))) + { + if ((msgDateExploded.tm_mday == cutOffDayExploded.tm_mday) && + (msgDateExploded.tm_month == cutOffDayExploded.tm_month) && + (msgDateExploded.tm_year == cutOffDayExploded.tm_year)) + result = PR_TRUE; + } + break; + default: + NS_ASSERTION(PR_FALSE, "invalid compare op for msg age"); + } + *pResult = result; + return err; +} + + +nsresult nsMsgSearchTerm::MatchSize (PRUint32 sizeToMatch, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + PRBool result = PR_FALSE; + // We reduce the sizeToMatch rather than supplied size + // as then we can do an exact match on the displayed value + // which will be less confusing to the user. + PRUint32 sizeToMatchKB = sizeToMatch; + + if (sizeToMatchKB < 1024) + sizeToMatchKB = 1024; + + sizeToMatchKB /= 1024; + + switch (m_operator) + { + case nsMsgSearchOp::IsGreaterThan: + if (sizeToMatchKB > m_value.u.size) + result = PR_TRUE; + break; + case nsMsgSearchOp::IsLessThan: + if (sizeToMatchKB < m_value.u.size) + result = PR_TRUE; + break; + case nsMsgSearchOp::Is: + if (sizeToMatchKB == m_value.u.size) + result = PR_TRUE; + break; + default: + break; + } + *pResult = result; + return NS_OK; +} + +nsresult nsMsgSearchTerm::MatchJunkStatus(const char *aJunkScore, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + nsMsgJunkStatus junkStatus; + if (aJunkScore && *aJunkScore) { + // cut off set at 50. this may change + // it works for our bayesian plugin, as "0" is good, and "100" is junk + // but it might need tweaking for other plugins + if ( atoi(aJunkScore) > 50 ) { + junkStatus = nsIJunkMailPlugin::JUNK; + } else { + junkStatus = nsIJunkMailPlugin::GOOD; + } + } + else { + // the in UI, we only show "junk" or "not junk" + // unknown, or nsIJunkMailPlugin::UNCLASSIFIED is shown as not junk + // so for the search to work as expected, treat unknown as not junk + junkStatus = nsIJunkMailPlugin::GOOD; + } + + nsresult rv = NS_OK; + PRBool matches = (junkStatus == m_value.u.junkStatus); + + switch (m_operator) + { + case nsMsgSearchOp::Is: + break; + case nsMsgSearchOp::Isnt: + matches = !matches; + break; + default: + rv = NS_ERROR_FAILURE; + NS_ASSERTION(PR_FALSE, "invalid compare op for junk status"); + } + + *pResult = matches; + return rv; +} + +nsresult nsMsgSearchTerm::MatchLabel(nsMsgLabelValue aLabelValue, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + PRBool result = PR_FALSE; + switch (m_operator) + { + case nsMsgSearchOp::Is: + if (m_value.u.label == aLabelValue) + result = PR_TRUE; + break; + default: + if (m_value.u.label != aLabelValue) + result = PR_TRUE; + break; + } + + *pResult = result; + return NS_OK; +} + +nsresult nsMsgSearchTerm::MatchStatus(PRUint32 statusToMatch, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + nsresult rv = NS_OK; + PRBool matches = (statusToMatch & m_value.u.msgStatus); + + switch (m_operator) + { + case nsMsgSearchOp::Is: + break; + case nsMsgSearchOp::Isnt: + matches = !matches; + break; + default: + rv = NS_ERROR_FAILURE; + NS_ERROR("invalid compare op for msg status"); + } + + *pResult = matches; + return rv; +} + +nsresult nsMsgSearchTerm::MatchKeyword(const char *keyword, PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + nsresult rv = NS_OK; + nsCAutoString keys; + + PRBool matches = PR_FALSE; + + switch (m_operator) + { + case nsMsgSearchOp::Is: + matches = !strcmp(keyword, m_value.string); + break; + case nsMsgSearchOp::Isnt: + matches = strcmp(keyword, m_value.string); + break; + case nsMsgSearchOp::DoesntContain: + case nsMsgSearchOp::Contains: + { + const char *keywordLoc = PL_strstr(keyword, m_value.string); + const char *startOfKeyword = keyword; + PRUint32 keywordLen = strlen(m_value.string); + while (keywordLoc) + { + // if the keyword is at the beginning of the string, then it's a match if + // it is either the whole string, or is followed by a space, it's a match. + if (keywordLoc == startOfKeyword || (keywordLoc[-1] == ' ')) + { + matches = keywordLen == strlen(keywordLoc) || (keywordLoc[keywordLen] == ' '); + if (matches) + break; + } + startOfKeyword = keywordLoc + keywordLen; + keywordLoc = PL_strstr(keyword, keywordLoc + keywordLen + 1); + } + } + break; + default: + rv = NS_ERROR_FAILURE; + NS_ERROR("invalid compare op for msg status"); + } + + *pResult = (m_operator == nsMsgSearchOp::DoesntContain) ? !matches : matches; + return rv; +} + +nsresult +nsMsgSearchTerm::MatchPriority (nsMsgPriorityValue priorityToMatch, + PRBool *pResult) +{ + NS_ENSURE_ARG_POINTER(pResult); + + nsresult err = NS_OK; + PRBool result=NS_OK; + + // Use this ugly little hack to get around the fact that enums don't have + // integer compare operators + int p1 = (priorityToMatch == nsMsgPriority::none) ? (int) nsMsgPriority::normal : (int) priorityToMatch; + int p2 = (int) m_value.u.priority; + + switch (m_operator) + { + case nsMsgSearchOp::IsHigherThan: + if (p1 > p2) + result = PR_TRUE; + break; + case nsMsgSearchOp::IsLowerThan: + if (p1 < p2) + result = PR_TRUE; + break; + case nsMsgSearchOp::Is: + if (p1 == p2) + result = PR_TRUE; + break; + default: + result = PR_FALSE; + err = NS_ERROR_FAILURE; + NS_ASSERTION(PR_FALSE, "invalid match operator"); + } + *pResult = result; + return err; +} + +// Lazily initialize the rfc822 header parser we're going to use to do +// header matching. +nsresult nsMsgSearchTerm::InitHeaderAddressParser() +{ + nsresult res = NS_OK; + + if (!m_headerAddressParser) + { + m_headerAddressParser = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID, &res); + } + return res; +} + +NS_IMPL_GETSET(nsMsgSearchTerm, Attrib, nsMsgSearchAttribValue, m_attribute) +NS_IMPL_GETSET(nsMsgSearchTerm, Op, nsMsgSearchOpValue, m_operator) +NS_IMPL_GETSET(nsMsgSearchTerm, MatchAll, PRBool, m_matchAll) + +NS_IMETHODIMP +nsMsgSearchTerm::GetValue(nsIMsgSearchValue **aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = new nsMsgSearchValueImpl(&m_value); + NS_IF_ADDREF(*aResult); + return NS_OK; +} + +NS_IMETHODIMP +nsMsgSearchTerm::SetValue(nsIMsgSearchValue* aValue) +{ + nsMsgResultElement::AssignValues (aValue, &m_value); + return NS_OK; +} + +NS_IMETHODIMP +nsMsgSearchTerm::GetBooleanAnd(PRBool *aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = (m_booleanOp == nsMsgSearchBooleanOp::BooleanAND); + return NS_OK; +} + +NS_IMETHODIMP +nsMsgSearchTerm::SetBooleanAnd(PRBool aValue) +{ + if (aValue) + m_booleanOp = nsMsgSearchBooleanOperator(nsMsgSearchBooleanOp::BooleanAND); + else + m_booleanOp = nsMsgSearchBooleanOperator(nsMsgSearchBooleanOp::BooleanOR); + return NS_OK; +} + +NS_IMETHODIMP +nsMsgSearchTerm::GetArbitraryHeader(char* *aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = ToNewCString(m_arbitraryHeader); + return NS_OK; +} + +NS_IMETHODIMP +nsMsgSearchTerm::SetArbitraryHeader(const char* aValue) +{ + m_arbitraryHeader = aValue; + return NS_OK; +} + +NS_IMPL_GETSET(nsMsgSearchTerm, BeginsGrouping, PRBool, mEndsGrouping) +NS_IMPL_GETSET(nsMsgSearchTerm, EndsGrouping, PRBool, mEndsGrouping) + +//----------------------------------------------------------------------------- +// nsMsgSearchScopeTerm implementation +//----------------------------------------------------------------------------- +nsMsgSearchScopeTerm::nsMsgSearchScopeTerm (nsIMsgSearchSession *session, + nsMsgSearchScopeValue attribute, + nsIMsgFolder *folder) +{ + m_attribute = attribute; + m_folder = folder; + m_searchServer = PR_TRUE; + m_searchSession = do_GetWeakReference(session); +} + +nsMsgSearchScopeTerm::nsMsgSearchScopeTerm () +{ + m_searchServer = PR_TRUE; +} + +nsMsgSearchScopeTerm::~nsMsgSearchScopeTerm () +{ + if (m_inputStream) + m_inputStream->Close(); + m_inputStream = nsnull; +} + +NS_IMPL_ISUPPORTS1(nsMsgSearchScopeTerm, nsIMsgSearchScopeTerm) + +NS_IMETHODIMP +nsMsgSearchScopeTerm::GetFolder(nsIMsgFolder **aResult) +{ + NS_IF_ADDREF(*aResult = m_folder); + return NS_OK; +} + +NS_IMETHODIMP +nsMsgSearchScopeTerm::GetSearchSession(nsIMsgSearchSession** aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + nsCOMPtr searchSession = do_QueryReferent (m_searchSession); + NS_IF_ADDREF(*aResult = searchSession); + return NS_OK; +} + +NS_IMETHODIMP nsMsgSearchScopeTerm::GetMailFile(nsILocalFile **aLocalFile) +{ + NS_ENSURE_ARG_POINTER(aLocalFile); + if (!m_localFile) + { + if (!m_folder) + return NS_ERROR_NULL_POINTER; + + m_folder->GetFilePath(getter_AddRefs(m_localFile)); + } + if (m_localFile) + { + NS_ADDREF(*aLocalFile = m_localFile); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsMsgSearchScopeTerm::GetInputStream(nsIInputStream **aInputStream) +{ + NS_ENSURE_ARG_POINTER(aInputStream); + nsresult rv = NS_OK; + if (!m_inputStream) + { + nsCOMPtr localFile; + rv = GetMailFile(getter_AddRefs(localFile)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = fileStream->Init(localFile, PR_RDONLY, 0664, PR_FALSE); //just have to read the messages + m_inputStream = do_QueryInterface(fileStream); + + } + NS_IF_ADDREF(*aInputStream = m_inputStream); + return rv; +} + +NS_IMETHODIMP nsMsgSearchScopeTerm::SetInputStream(nsIInputStream *aInputStream) +{ + if (!aInputStream && m_inputStream) + m_inputStream->Close(); + m_inputStream = aInputStream; + return NS_OK; +} + +nsresult nsMsgSearchScopeTerm::TimeSlice (PRBool *aDone) +{ + return m_adapter->Search(aDone); +} + +nsresult nsMsgSearchScopeTerm::InitializeAdapter (nsISupportsArray *termList) +{ + if (m_adapter) + return NS_OK; + + nsresult err = NS_OK; + + switch (m_attribute) + { + case nsMsgSearchScope::onlineMail: + m_adapter = new nsMsgSearchOnlineMail (this, termList); + break; + case nsMsgSearchScope::offlineMail: + m_adapter = new nsMsgSearchOfflineMail (this, termList); + break; + case nsMsgSearchScope::newsEx: + NS_ASSERTION(PR_FALSE, "not supporting newsEx yet"); + break; + case nsMsgSearchScope::news: + m_adapter = new nsMsgSearchNews (this, termList); + break; + case nsMsgSearchScope::allSearchableGroups: + NS_ASSERTION(PR_FALSE, "not supporting allSearchableGroups yet"); + break; + case nsMsgSearchScope::LDAP: + NS_ASSERTION(PR_FALSE, "not supporting LDAP yet"); + break; + case nsMsgSearchScope::localNews: + m_adapter = new nsMsgSearchOfflineNews (this, termList); + break; + default: + NS_ASSERTION(PR_FALSE, "invalid scope"); + err = NS_ERROR_FAILURE; + } + + if (m_adapter) + err = m_adapter->ValidateTerms (); + + return err; +} + + +char *nsMsgSearchScopeTerm::GetStatusBarName () +{ + return nsnull; +} + + +//----------------------------------------------------------------------------- +// nsMsgResultElement implementation +//----------------------------------------------------------------------------- + + +nsMsgResultElement::nsMsgResultElement(nsIMsgSearchAdapter *adapter) +{ + NS_NewISupportsArray(getter_AddRefs(m_valueList)); + m_adapter = adapter; +} + + +nsMsgResultElement::~nsMsgResultElement () +{ +} + + +nsresult nsMsgResultElement::AddValue (nsIMsgSearchValue *value) +{ + m_valueList->AppendElement (value); + return NS_OK; +} + +nsresult nsMsgResultElement::AddValue (nsMsgSearchValue *value) +{ + nsMsgSearchValueImpl* valueImpl = new nsMsgSearchValueImpl(value); + delete value; // we keep the nsIMsgSearchValue, not + // the nsMsgSearchValue + return AddValue(valueImpl); +} + + +nsresult nsMsgResultElement::AssignValues (nsIMsgSearchValue *src, nsMsgSearchValue *dst) +{ + NS_ENSURE_ARG_POINTER(src); + NS_ENSURE_ARG_POINTER(dst); + + // Yes, this could be an operator overload, but nsMsgSearchValue is totally public, so I'd + // have to define a derived class with nothing by operator=, and that seems like a bit much + nsresult err = NS_OK; + src->GetAttrib(&dst->attribute); + switch (dst->attribute) + { + case nsMsgSearchAttrib::Priority: + err = src->GetPriority(&dst->u.priority); + break; + case nsMsgSearchAttrib::Date: + err = src->GetDate(&dst->u.date); + break; + case nsMsgSearchAttrib::HasAttachmentStatus: + case nsMsgSearchAttrib::MsgStatus: + err = src->GetStatus(&dst->u.msgStatus); + break; + case nsMsgSearchAttrib::MessageKey: + err = src->GetMsgKey(&dst->u.key); + break; + case nsMsgSearchAttrib::AgeInDays: + err = src->GetAge(&dst->u.age); + break; + case nsMsgSearchAttrib::Label: + err = src->GetLabel(&dst->u.label); + break; + case nsMsgSearchAttrib::JunkStatus: + err = src->GetJunkStatus(&dst->u.junkStatus); + break; + case nsMsgSearchAttrib::Size: + err = src->GetSize(&dst->u.size); + break; + default: + if (dst->attribute < nsMsgSearchAttrib::kNumMsgSearchAttributes) + { + NS_ASSERTION(IS_STRING_ATTRIBUTE(dst->attribute), "assigning non-string result"); + nsXPIDLString unicodeString; + err = src->GetStr(getter_Copies(unicodeString)); + dst->string = ToNewUTF8String(unicodeString); + } + else + err = NS_ERROR_INVALID_ARG; + } + return err; +} + + +nsresult nsMsgResultElement::GetValue (nsMsgSearchAttribValue attrib, + nsMsgSearchValue **outValue) const +{ + nsresult err = NS_OK; + nsCOMPtr value; + *outValue = NULL; + + PRUint32 count; + m_valueList->Count(&count); + for (PRUint32 i = 0; i < count && err != NS_OK; i++) + { + m_valueList->QueryElementAt(i, NS_GET_IID(nsIMsgSearchValue), + (void **)getter_AddRefs(value)); + + nsMsgSearchAttribValue valueAttribute; + value->GetAttrib(&valueAttribute); + if (attrib == valueAttribute) + { + *outValue = new nsMsgSearchValue; + if (*outValue) + { + err = AssignValues (value, *outValue); + err = NS_OK; + } + else + err = NS_ERROR_OUT_OF_MEMORY; + } + } + return err; +} + +nsresult nsMsgResultElement::GetPrettyName (nsMsgSearchValue **value) +{ + return GetValue (nsMsgSearchAttrib::Location, value); +} + +nsresult nsMsgResultElement::Open (void *window) +{ + return NS_ERROR_NULL_POINTER; +} + + diff --git a/mailnews/base/util/nsMsgDBFolder.cpp b/mailnews/base/util/nsMsgDBFolder.cpp index af185b39a4c..989ca859bda 100644 --- a/mailnews/base/util/nsMsgDBFolder.cpp +++ b/mailnews/base/util/nsMsgDBFolder.cpp @@ -183,7 +183,6 @@ nsMsgDBFolder::nsMsgDBFolder(void) mHaveParsedURI(PR_FALSE), mIsServerIsValid(PR_FALSE), mIsServer(PR_FALSE), - mBaseMessageURI(nsnull), mInVFEditSearchScope (PR_FALSE) { NS_NewISupportsArray(getter_AddRefs(mSubFolders)); @@ -200,8 +199,6 @@ nsMsgDBFolder::nsMsgDBFolder(void) nsMsgDBFolder::~nsMsgDBFolder(void) { - CRTFREEIF(mBaseMessageURI); - if (--mInstanceCount == 0) { NS_IF_RELEASE(gCollationKeyGenerator); CRTFREEIF(kLocalizedInboxName); @@ -4845,10 +4842,10 @@ NS_IMETHODIMP nsMsgDBFolder::GetBaseMessageURI(char **baseMessageURI) { NS_ENSURE_ARG_POINTER(baseMessageURI); - if (!mBaseMessageURI) + if (mBaseMessageURI.IsEmpty()) return NS_ERROR_FAILURE; - *baseMessageURI = nsCRT::strdup(mBaseMessageURI); + *baseMessageURI = ToNewCString(mBaseMessageURI); return NS_OK; } diff --git a/mailnews/base/util/nsMsgDBFolder.h b/mailnews/base/util/nsMsgDBFolder.h index a2e552d411f..04ceebfee83 100644 --- a/mailnews/base/util/nsMsgDBFolder.h +++ b/mailnews/base/util/nsMsgDBFolder.h @@ -236,7 +236,7 @@ protected: PRBool mIsServer; nsString mName; nsCOMPtr mPath; - char * mBaseMessageURI; //The uri with the message scheme + nsCString mBaseMessageURI; //The uri with the message scheme PRBool mInVFEditSearchScope ; // non persistant state used by the virtual folder UI diff --git a/mailnews/imap/src/nsIMAPBodyShell.cpp b/mailnews/imap/src/nsIMAPBodyShell.cpp index c6ec7f15e32..8547a5de0ed 100644 --- a/mailnews/imap/src/nsIMAPBodyShell.cpp +++ b/mailnews/imap/src/nsIMAPBodyShell.cpp @@ -265,7 +265,7 @@ PRInt32 nsIMAPBodyShell::Generate(char *partNum) PRUint32 messageSize = m_protocolConnection->GetMessageSize(GetUID().get(), PR_TRUE); m_protocolConnection->SetContentModified(IMAP_CONTENT_NOT_MODIFIED); // So that when we cache it, we know we have the whole message if (!DeathSignalReceived()) - m_protocolConnection->FallbackToFetchWholeMsg(GetUID().get(), messageSize); + m_protocolConnection->FallbackToFetchWholeMsg(GetUID(), messageSize); contentLength = (PRInt32) messageSize; // ugh } else @@ -502,7 +502,7 @@ PRInt32 nsIMAPBodypart::GeneratePart(nsIMAPBodyShell *aShell, PRBool stream, PRB PRBool fetchingSpecificPart = (generatingPart && !PL_strcmp(generatingPart, m_partNumberString)); aShell->GetConnection()->Log("SHELL","GENERATE-Part-Inline",m_partNumberString); - aShell->GetConnection()->FetchTryChunking(aShell->GetUID().get(), kMIMEPart, PR_TRUE, m_partNumberString, m_partLength, !fetchingSpecificPart); + aShell->GetConnection()->FetchTryChunking(aShell->GetUID(), kMIMEPart, PR_TRUE, m_partNumberString, m_partLength, !fetchingSpecificPart); } return m_partLength; // the part length has been filled in from the BODYSTRUCTURE response } diff --git a/mailnews/imap/src/nsImapIncomingServer.cpp b/mailnews/imap/src/nsImapIncomingServer.cpp index 6720b76402c..10138774378 100644 --- a/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mailnews/imap/src/nsImapIncomingServer.cpp @@ -67,7 +67,6 @@ #include "nsMsgFolderFlags.h" #include "prmem.h" #include "plstr.h" -#include "nsXPIDLString.h" #include "nsIMsgFolder.h" #include "nsIMsgWindow.h" #include "nsIMsgImapMailFolder.h" @@ -158,7 +157,7 @@ NS_IMETHODIMP nsImapIncomingServer::SetKey(const nsACString& aKey) // override hostSession->SetDeleteIsMoveToTrashForHost(key.get(), deleteModel == nsMsgImapDeleteModels::MoveToTrash); hostSession->SetShowDeletedMessagesForHost(key.get(), deleteModel == nsMsgImapDeleteModels::IMAPDelete); - nsCString onlineDir; + nsCAutoString onlineDir; rv = GetServerDirectory(onlineDir); NS_ENSURE_SUCCESS(rv, rv); if (!onlineDir.IsEmpty()) @@ -200,9 +199,8 @@ NS_IMETHODIMP nsImapIncomingServer::SetKey(const nsACString& aKey) // override NS_IMETHODIMP nsImapIncomingServer::GetConstructedPrettyName(nsAString& retval) { - - nsCString username; - nsCString hostName; + nsCAutoString username; + nsCAutoString hostName; nsresult rv; nsCOMPtr accountManager = @@ -360,7 +358,7 @@ nsImapIncomingServer::GetDeleteModel(PRInt32 *retval) { NS_ENSURE_ARG(retval); - nsCString redirectorType; + nsCAutoString redirectorType; GetRedirectorType(redirectorType); if (redirectorType.Equals("aol")) { @@ -696,7 +694,7 @@ nsImapIncomingServer::GetImapConnection(nsIEventTarget *aEventTarget, nsCOMPtr freeConnection; PRBool isBusy = PR_FALSE; PRBool isInboxConnection = PR_FALSE; - nsCString redirectorType; + nsCAutoString redirectorType; PR_CEnterMonitor(this); @@ -740,8 +738,8 @@ nsImapIncomingServer::GetImapConnection(nsIEventTarget *aEventTarget, { rv = connection->CanHandleUrl(aImapUrl, &canRunUrlImmediately, &canRunButBusy); #ifdef DEBUG_bienvenu - nsXPIDLCString curSelectedFolderName; - if (connection) + nsCAutoString curSelectedFolderName; + if (connection) connection->GetSelectedMailboxName(getter_Copies(curSelectedFolderName)); // check that no other connection is in the same selected state. if (!curSelectedFolderName.IsEmpty()) @@ -753,7 +751,7 @@ nsImapIncomingServer::GetImapConnection(nsIEventTarget *aEventTarget, nsCOMPtr otherConnection = do_QueryElementAt(m_connectionCache, j); if (otherConnection) { - nsXPIDLCString otherSelectedFolderName; + nsCAutoString otherSelectedFolderName; otherConnection->GetSelectedMailboxName(getter_Copies(otherSelectedFolderName)); NS_ASSERTION(!curSelectedFolderName.Equals(otherSelectedFolderName), "two connections selected on same folder"); } @@ -785,7 +783,7 @@ nsImapIncomingServer::GetImapConnection(nsIEventTarget *aEventTarget, freeConnection = connection; else // check which is the better free connection to use. { // We prefer one not in the selected state. - nsCString selectedFolderName; + nsCAutoString selectedFolderName; connection->GetSelectedMailboxName(getter_Copies(selectedFolderName)); if (selectedFolderName.IsEmpty()) freeConnection = connection; @@ -1041,7 +1039,7 @@ void nsImapIncomingServer::GetPFCName(nsACString& aPfcname) { if(NS_SUCCEEDED(GetStringBundle())) { - nsString pfcName; + nsAutoString pfcName; nsresult res = m_stringBundle->GetStringFromID(IMAP_PERSONAL_FILING_CABINET, getter_Copies(pfcName)); if (NS_SUCCEEDED(res)) CopyUTF16toUTF8(pfcName, m_pfcName); @@ -1083,12 +1081,12 @@ nsresult nsImapIncomingServer::GetPFCForStringId(PRBool createIfMissing, PRInt32 nsresult rv = GetPFC(createIfMissing, getter_AddRefs(pfcParent)); NS_ENSURE_SUCCESS(rv, rv); - nsXPIDLCString pfcURI; + nsCString pfcURI; pfcParent->GetURI(getter_Copies(pfcURI)); rv = GetStringBundle(); NS_ENSURE_SUCCESS(rv, rv); - nsString pfcName; + nsAutoString pfcName; rv = m_stringBundle->GetStringFromID(stringId, getter_Copies(pfcName)); NS_ENSURE_SUCCESS(rv, rv); nsCAutoString pfcMailUri(pfcURI); @@ -1228,7 +1226,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder parentUri.Append('/'); parentUri.Append(parentName); } - if (folderPath.LowerCaseEqualsLiteral("INBOX") && + if (folderPath.LowerCaseEqualsLiteral("inbox") && hierarchyDelimiter == kOnlineHierarchySeparatorNil) { hierarchyDelimiter = '/'; // set to default in this case (as in 4.x) @@ -1246,7 +1244,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder // nsCString possibleName(aSpec->allocatedPathName); uri.Append('/'); uri.Append(dupFolderPath); - PRBool caseInsensitive = dupFolderPath.LowerCaseEqualsLiteral("INBOX"); + PRBool caseInsensitive = dupFolderPath.LowerCaseEqualsLiteral("inbox"); a_nsIFolder->GetChildWithURI(uri.get(), PR_TRUE, caseInsensitive, getter_AddRefs(child)); // if we couldn't find this folder by URI, tell the imap code it's a new folder to us *aNewFolder = !child; @@ -1259,7 +1257,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder { nsCOMPtr parent; PRBool parentIsNew; - caseInsensitive = parentName.LowerCaseEqualsLiteral("INBOX"); + caseInsensitive = parentName.LowerCaseEqualsLiteral("inbox"); a_nsIFolder->GetChildWithURI(parentUri.get(), PR_TRUE, caseInsensitive, getter_AddRefs(parent)); if (!parent /* || parentFolder->GetFolderNeedsAdded()*/) { @@ -1269,7 +1267,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder } } hostFolder->CreateClientSubfolderInfo(dupFolderPath.get(), hierarchyDelimiter,boxFlags, PR_FALSE); - caseInsensitive = dupFolderPath.LowerCaseEqualsLiteral("INBOX"); + caseInsensitive = dupFolderPath.LowerCaseEqualsLiteral("inbox"); a_nsIFolder->GetChildWithURI(uri.get(), PR_TRUE, caseInsensitive, getter_AddRefs(child)); } if (child) @@ -1280,9 +1278,9 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder PRBool isAOLServer = PR_FALSE; GetIsAOLServer(&isAOLServer); - - nsXPIDLCString onlineName; - nsXPIDLString unicodeName; + + nsCAutoString onlineName; + nsAutoString unicodeName; imapFolder->SetVerifiedAsOnlineFolder(PR_TRUE); imapFolder->SetHierarchyDelimiter(hierarchyDelimiter); if (boxFlags & kImapTrash) @@ -1314,12 +1312,12 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder if (hierarchyDelimiter != '/') nsImapUrl::UnescapeSlashes(folderName.BeginWriting()); if (NS_SUCCEEDED(CopyMUTF7toUTF16(folderName, unicodeName))) - child->SetPrettyName(unicodeName); + child->SetPrettyName(unicodeName.get()); // Call ConvertFolderName() and HideFolderName() to do special folder name // mapping and hiding, if configured to do so. For example, need to hide AOL's // 'RECYCLE_OUT' & convert a few AOL folder names. Regular imap accounts // will do no-op in the calls. - nsString convertedName; + nsAutoString convertedName; PRBool hideFolder; rv = HideFolderName(onlineName, &hideFolder); if (hideFolder) @@ -1331,7 +1329,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const nsACString& folder { rv = ConvertFolderName(onlineName, convertedName); //make sure rv value is not crunched, it is used to SetPrettyName - nsCString redirectorType; + nsCAutoString redirectorType; GetRedirectorType(redirectorType); //Sent mail folder as per aol/netscape webmail if ((redirectorType.EqualsLiteral("aol") && onlineName.EqualsLiteral("Sent Items")) || (redirectorType.EqualsLiteral("netscape") && onlineName.EqualsLiteral("Sent"))) @@ -1438,7 +1436,7 @@ NS_IMETHODIMP nsImapIncomingServer::GetRedirectorType(nsACString& redirectorType // redirectory type if (redirectorType.LowerCaseEqualsLiteral("aol")) { - nsCString hostName; + nsCAutoString hostName; GetHostName(hostName); if (hostName.LowerCaseEqualsLiteral("imap.mail.netcenter.com")) SetRedirectorType(NS_LITERAL_CSTRING("netscape")); @@ -1454,7 +1452,7 @@ NS_IMETHODIMP nsImapIncomingServer::GetRedirectorType(nsACString& redirectorType rv = CreateHostSpecificPrefName("default_redirector_type", prefName); NS_ENSURE_SUCCESS(rv,rv); - nsCString defaultRedirectorType; + nsCAutoString defaultRedirectorType; nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); @@ -1537,7 +1535,7 @@ NS_IMETHODIMP nsImapIncomingServer::ConvertFolderName(const nsACString& original // Get string bundle based on redirector type and convert folder name. nsCOMPtr stringBundle; nsCAutoString propertyURL; - nsCString redirectorType; + nsCAutoString redirectorType; GetRedirectorType(redirectorType); if (redirectorType.IsEmpty()) return NS_ERROR_FAILURE; // return if no redirector type @@ -1748,7 +1746,7 @@ NS_IMETHODIMP nsImapIncomingServer::DiscoveryDone() if (NS_SUCCEEDED(rv) && numFolders > 1) { - nsString trashName; + nsAutoString trashName; if (NS_SUCCEEDED(GetTrashFolderName(trashName))) { nsIMsgFolder *trashFolders[2]; @@ -1757,7 +1755,7 @@ NS_IMETHODIMP nsImapIncomingServer::DiscoveryDone() { for (PRUint32 i = 0; i < numFolders; i++) { - nsString folderName; + nsAutoString folderName; if (NS_SUCCEEDED(trashFolders[i]->GetName(getter_Copies(folderName)))) { if (!folderName.Equals(trashName)) @@ -2097,7 +2095,7 @@ NS_IMETHODIMP nsImapIncomingServer::FormatStringWithHostNameByID(PRInt32 aMsgId GetStringBundle(); if (m_stringBundle) { - nsCString hostName; + nsCAutoString hostName; res = GetRealHostName(hostName); if (NS_SUCCEEDED(res)) { @@ -2408,8 +2406,7 @@ nsresult nsImapIncomingServer::RequestOverrideInfo(nsIMsgWindow *aMsgWindow) { nsresult rv; nsCAutoString contractID(NS_MSGLOGONREDIRECTORSERVICE_CONTRACTID); - nsCString redirectorType; - + nsCAutoString redirectorType; GetRedirectorType(redirectorType); contractID.Append('/'); contractID.Append(redirectorType); @@ -2420,12 +2417,11 @@ nsresult nsImapIncomingServer::RequestOverrideInfo(nsIMsgWindow *aMsgWindow) rv = QueryInterface(NS_GET_IID(nsIMsgLogonRedirectionRequester), getter_AddRefs(logonRedirectorRequester)); if (NS_SUCCEEDED(rv)) { - nsCString password; - nsCString userName; + nsCAutoString password; + nsCAutoString userName; PRBool requiresPassword = PR_TRUE; GetRealUsername(userName); m_logonRedirector->RequiresPassword(userName.get(), redirectorType.get(), &requiresPassword); - if (requiresPassword) { GetPassword(password); @@ -2759,10 +2755,8 @@ nsImapIncomingServer::AddTo(const nsACString &aName, PRBool addAsSubscribed, NS_IMETHODIMP nsImapIncomingServer::StopPopulating(nsIMsgWindow *aMsgWindow) { - nsresult rv; - nsCOMPtr listener; - rv = GetSubscribeListener(getter_AddRefs(listener)); + nsresult rv = GetSubscribeListener(getter_AddRefs(listener)); NS_ENSURE_SUCCESS(rv, rv); rv = listener->OnDonePopulating(); @@ -3025,7 +3019,7 @@ nsImapIncomingServer::CreateHostSpecificPrefName(const char *prefPrefix, nsCAuto prefName = prefPrefix; prefName.Append('.'); - prefName.Append(hostName.get()); + prefName.Append(hostName); return NS_OK; } @@ -3431,7 +3425,7 @@ nsImapIncomingServer::OnUserOrHostNameChanged(const nsACString& oldName, const n // reloaded (ie, DiscoverMailboxList() will be invoked in nsImapProtocol). nsCOMPtr hostSessionList = do_GetService(kCImapHostSessionListCID, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCString serverKey; + nsCAutoString serverKey; rv = GetKey(serverKey); NS_ENSURE_SUCCESS(rv, rv); hostSessionList->SetHaveWeEverDiscoveredFoldersForHost(serverKey.get(), PR_FALSE); @@ -3448,10 +3442,9 @@ nsImapIncomingServer::GetUriWithNamespacePrefixIfNecessary(PRInt32 namespaceType nsACString& convertedUri) { nsresult rv = NS_OK; - nsCString serverKey; + nsCAutoString serverKey; rv = GetKey(serverKey); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr hostSessionList = do_GetService(kCImapHostSessionListCID, &rv); nsIMAPNamespace *ns = nsnull; rv = hostSessionList->GetDefaultNamespaceOfTypeForHost(serverKey.get(), (EIMAPNamespaceType)namespaceType, ns); @@ -3461,7 +3454,7 @@ nsImapIncomingServer::GetUriWithNamespacePrefixIfNecessary(PRInt32 namespaceType if (!namespacePrefix.IsEmpty()) { // check if namespacePrefix is the same as the online directory; if so, ignore it. - nsCString onlineDir; + nsCAutoString onlineDir; rv = GetServerDirectory(onlineDir); NS_ENSURE_SUCCESS(rv, rv); if (!onlineDir.IsEmpty()) @@ -3501,7 +3494,7 @@ NS_IMETHODIMP nsImapIncomingServer::GetTrashFolderName(nsAString& retval) NS_IMETHODIMP nsImapIncomingServer::SetTrashFolderName(const nsAString& chvalue) { // clear trash flag from the old pref - nsString oldTrashName; + nsAutoString oldTrashName; nsresult rv = GetTrashFolderName(oldTrashName); if (NS_SUCCEEDED(rv)) { diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 3f77b2ffc85..e31a444572f 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -7602,7 +7602,7 @@ NS_IMETHODIMP nsImapMailFolder::MatchName(nsString *name, PRBool *matches) nsresult nsImapMailFolder::CreateBaseMessageURI(const char *aURI) { - return nsCreateImapBaseMessageURI(aURI, &mBaseMessageURI); + return nsCreateImapBaseMessageURI(aURI, mBaseMessageURI); } NS_IMETHODIMP nsImapMailFolder::GetFolderURL(char **aFolderURL) diff --git a/mailnews/imap/src/nsImapOfflineSync.cpp b/mailnews/imap/src/nsImapOfflineSync.cpp index ab5f001b9de..1deeca39b8d 100644 --- a/mailnews/imap/src/nsImapOfflineSync.cpp +++ b/mailnews/imap/src/nsImapOfflineSync.cpp @@ -41,7 +41,6 @@ #include "nsImapOfflineSync.h" #include "nsImapMailFolder.h" #include "nsMsgFolderFlags.h" -#include "nsXPIDLString.h" #include "nsIRDFService.h" #include "nsMsgBaseCID.h" #include "nsRDFCID.h" @@ -302,7 +301,7 @@ void nsImapOfflineSync::ProcessKeywordOperation(nsIMsgOfflineImapOperation *op) nsMsgKeyArray matchingKeywordKeys; PRUint32 currentKeyIndex = m_KeyIndex; - nsXPIDLCString keywords; + nsCAutoString keywords; if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAddKeywords) currentOp->GetKeywordsToAdd(getter_Copies(keywords)); else @@ -323,7 +322,7 @@ void nsImapOfflineSync::ProcessKeywordOperation(nsIMsgOfflineImapOperation *op) getter_AddRefs(currentOp)); if (currentOp) { - nsXPIDLCString curOpKeywords; + nsCAutoString curOpKeywords; nsOfflineImapOperationType operation; currentOp->GetOperation(&operation); if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAddKeywords) @@ -394,7 +393,7 @@ nsImapOfflineSync::ProcessAppendMsgOperation(nsIMsgOfflineImapOperation *current rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), tmpFile, PR_WRONLY | PR_CREATE_FILE, 00600); if (NS_SUCCEEDED(rv) && outputStream) { - nsXPIDLCString moveDestination; + nsCString moveDestination; currentOp->GetDestinationFolderURI(getter_Copies(moveDestination)); nsCOMPtr rdf(do_GetService(kRDFServiceCID, &rv)); nsCOMPtr res; @@ -477,7 +476,7 @@ void nsImapOfflineSync::ProcessMoveOperation(nsIMsgOfflineImapOperation *op) { nsMsgKeyArray matchingFlagKeys ; PRUint32 currentKeyIndex = m_KeyIndex; - nsXPIDLCString moveDestination; + nsCString moveDestination; op->GetDestinationFolderURI(getter_Copies(moveDestination)); PRBool moveMatches = PR_TRUE; nsCOMPtr currentOp = op; @@ -494,7 +493,7 @@ void nsImapOfflineSync::ProcessMoveOperation(nsIMsgOfflineImapOperation *op) if (++currentKeyIndex < m_CurrentKeys.GetSize()) { - nsXPIDLCString nextDestination; + nsCString nextDestination; nsresult rv = m_currentDB->GetOfflineOpForKey(m_CurrentKeys[currentKeyIndex], PR_FALSE, getter_AddRefs(currentOp)); moveMatches = PR_FALSE; if (NS_SUCCEEDED(rv) && currentOp) @@ -504,7 +503,7 @@ void nsImapOfflineSync::ProcessMoveOperation(nsIMsgOfflineImapOperation *op) if (opType & nsIMsgOfflineImapOperation::kMsgMoved) { currentOp->GetDestinationFolderURI(getter_Copies(nextDestination)); - moveMatches = nsCRT::strcmp(moveDestination, nextDestination) == 0; + moveMatches = moveDestination.Equals(nextDestination); } } } @@ -591,7 +590,7 @@ void nsImapOfflineSync::ProcessCopyOperation(nsIMsgOfflineImapOperation *current { nsMsgKeyArray matchingFlagKeys; PRUint32 currentKeyIndex = m_KeyIndex; - nsXPIDLCString copyDestination; + nsCString copyDestination; currentOp->GetCopyDestination(0, getter_Copies(copyDestination)); PRBool copyMatches = PR_TRUE; @@ -607,7 +606,7 @@ void nsImapOfflineSync::ProcessCopyOperation(nsIMsgOfflineImapOperation *current if (++currentKeyIndex < m_CurrentKeys.GetSize()) { - nsXPIDLCString nextDestination; + nsCString nextDestination; nsresult rv = m_currentDB->GetOfflineOpForKey(m_CurrentKeys[currentKeyIndex], PR_FALSE, ¤tOp); copyMatches = PR_FALSE; if (NS_SUCCEEDED(rv) && currentOp) @@ -617,7 +616,7 @@ void nsImapOfflineSync::ProcessCopyOperation(nsIMsgOfflineImapOperation *current if (opType & nsIMsgOfflineImapOperation::kMsgCopy) { currentOp->GetCopyDestination(0, getter_Copies(nextDestination)); - copyMatches = nsCRT::strcmp(copyDestination, nextDestination) == 0; + copyMatches = copyDestination.Equals(nextDestination); } } } @@ -702,7 +701,7 @@ PRBool nsImapOfflineSync::CreateOfflineFolder(nsIMsgFolder *folder) nsCOMPtr imapFolder = do_QueryInterface(parent); nsCOMPtr createFolderURI; - nsXPIDLCString onlineName; + nsCString onlineName; imapFolder->GetOnlineName(getter_Copies(onlineName)); NS_ConvertASCIItoUTF16 folderName(onlineName); diff --git a/mailnews/imap/src/nsImapProtocol.cpp b/mailnews/imap/src/nsImapProtocol.cpp index 06c3a2d49d5..16f6641005c 100644 --- a/mailnews/imap/src/nsImapProtocol.cpp +++ b/mailnews/imap/src/nsImapProtocol.cpp @@ -70,7 +70,6 @@ #include "nsIStreamListenerTee.h" #include "nsXPCOMCIDInternal.h" #include "nsNetUtil.h" -#include "nsXPIDLString.h" #include "nsReadableUtils.h" #include "nsIPipe.h" #include "nsIMsgFolder.h" @@ -343,9 +342,9 @@ nsresult nsImapProtocol::GlobalInitialization() prefBranch->GetBoolPref("mail.imap.expunge_after_delete", &gExpungeAfterDelete); prefBranch->GetBoolPref("mail.imap.check_deleted_before_expunge", &gCheckDeletedBeforeExpunge); prefBranch->GetIntPref("mailnews.tcptimeout", &gResponseTimeout); - nsXPIDLCString customDBHeaders; + nsCString customDBHeaders; prefBranch->GetCharPref("mailnews.customDBHeaders", getter_Copies(customDBHeaders)); - gCustomDBHeaders.ParseString(customDBHeaders, " "); + gCustomDBHeaders.ParseString(customDBHeaders.get(), " "); return NS_OK; } @@ -726,9 +725,8 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer) && socketType == nsIMsgIncomingServer::useSSL) ? SECURE_IMAP_PORT :IMAP_PORT; } - - nsCString hostName; - nsCOMPtr socketService = + nsCAutoString hostName; + nsCOMPtr socketService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv) && aURL) { @@ -1949,7 +1947,7 @@ char *nsImapProtocol::GetServerCommandTag() void nsImapProtocol::ProcessSelectedStateURL() { - nsXPIDLCString mailboxName; + nsCString mailboxName; PRBool bMessageIdsAreUids = PR_TRUE; imapMessageFlagsType msgFlags = 0; nsCString urlHost; @@ -1973,20 +1971,20 @@ void nsImapProtocol::ProcessSelectedStateURL() { if (GetServerStateParser().GetSelectedMailboxName() && PL_strcmp(GetServerStateParser().GetSelectedMailboxName(), - mailboxName)) + mailboxName.get())) { // we are selected in another folder if (m_closeNeededBeforeSelect) Close(); if (GetServerStateParser().LastCommandSuccessful()) { selectIssued = PR_TRUE; - AutoSubscribeToMailboxIfNecessary(mailboxName); - SelectMailbox(mailboxName); + AutoSubscribeToMailboxIfNecessary(mailboxName.get()); + SelectMailbox(mailboxName.get()); } } else if (!GetServerStateParser().GetSelectedMailboxName()) { // why are we in the selected state with no box name? - SelectMailbox(mailboxName); + SelectMailbox(mailboxName.get()); selectIssued = PR_TRUE; } else @@ -2007,13 +2005,13 @@ void nsImapProtocol::ProcessSelectedStateURL() else { // go to selected state - AutoSubscribeToMailboxIfNecessary(mailboxName); - SelectMailbox(mailboxName); + AutoSubscribeToMailboxIfNecessary(mailboxName.get()); + SelectMailbox(mailboxName.get()); selectIssued = GetServerStateParser().LastCommandSuccessful(); } if (selectIssued) - RefreshACLForFolderIfNecessary(mailboxName); + RefreshACLForFolderIfNecessary(mailboxName.get()); PRBool uidValidityOk = PR_TRUE; if (GetServerStateParser().LastCommandSuccessful() && selectIssued && @@ -2083,7 +2081,7 @@ void nsImapProtocol::ProcessSelectedStateURL() case nsIImapUrl::nsImapMsgDownloadForOffline: case nsIImapUrl::nsImapMsgPreview: { - nsXPIDLCString messageIdString; + nsCString messageIdString; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); // we don't want to send the flags back in a group // GetServerStateParser().ResetFlagInfo(0); @@ -2094,7 +2092,7 @@ void nsImapProtocol::ProcessSelectedStateURL() SetProgressString(IMAP_FOLDER_RECEIVING_MESSAGE_OF); m_progressIndex = 0; - m_progressCount = CountMessagesInIdString(messageIdString); + m_progressCount = CountMessagesInIdString(messageIdString.get()); // we need to set this so we'll get the msg from the memory cache. if (m_imapAction == nsIImapUrl::nsImapMsgFetchPeek) @@ -2130,7 +2128,7 @@ void nsImapProtocol::ProcessSelectedStateURL() nsIMAPBodyShell *foundShell = nsnull; res = m_hostSessionList->FindShellInCacheForHost(GetImapServerKey(), - GetServerStateParser().GetSelectedMailboxName(), messageIdString, modType, &foundShell); + GetServerStateParser().GetSelectedMailboxName(), messageIdString.get(), modType, &foundShell); if (!foundShell) { // The shell wasn't in the cache. Deal with this case later. @@ -2148,7 +2146,7 @@ void nsImapProtocol::ProcessSelectedStateURL() foundShell->SetConnection(this); GetServerStateParser().UseCachedShell(foundShell); //Set the current uid in server state parser (in case it was used for new mail msgs earlier). - GetServerStateParser().SetCurrentResponseUID((PRUint32)atoi(messageIdString)); + GetServerStateParser().SetCurrentResponseUID((PRUint32)atoi(messageIdString.get())); foundShell->Generate(imappart); GetServerStateParser().UseCachedShell(NULL); } @@ -2163,7 +2161,7 @@ void nsImapProtocol::ProcessSelectedStateURL() else { // downloading a single message: try to do it by bodystructure, and/or do it by chunks - PRUint32 messageSize = GetMessageSize(messageIdString, bMessageIdsAreUids); + PRUint32 messageSize = GetMessageSize(messageIdString.get(), bMessageIdsAreUids); // We need to check the format_out bits to see if we are allowed to leave out parts, // or if we are required to get the whole thing. Some instances where we are allowed // to do it by parts: when viewing a message, replying to a message, or viewing its source @@ -2206,7 +2204,7 @@ void nsImapProtocol::ProcessSelectedStateURL() if (bMessageIdsAreUids) { res = m_hostSessionList->FindShellInCacheForHost(GetImapServerKey(), - GetServerStateParser().GetSelectedMailboxName(), messageIdString, modType, &foundShell); + GetServerStateParser().GetSelectedMailboxName(), messageIdString.get(), modType, &foundShell); if (foundShell) { Log("SHELL",NULL,"Loading message, using cached shell."); @@ -2214,7 +2212,7 @@ void nsImapProtocol::ProcessSelectedStateURL() foundShell->SetConnection(this); GetServerStateParser().UseCachedShell(foundShell); //Set the current uid in server state parser (in case it was used for new mail msgs earlier). - GetServerStateParser().SetCurrentResponseUID((PRUint32)atoi(messageIdString)); + GetServerStateParser().SetCurrentResponseUID((PRUint32)atoi(messageIdString.get())); foundShell->Generate(NULL); GetServerStateParser().UseCachedShell(NULL); } @@ -2236,7 +2234,7 @@ void nsImapProtocol::ProcessSelectedStateURL() && m_imapAction != nsIImapUrl::nsImapMsgPreview && m_imapAction != nsIImapUrl::nsImapMsgFetchPeek) { - PRUint32 uid = atoi(messageIdString); + PRUint32 uid = atoi(messageIdString.get()); PRInt32 index; PRBool foundIt; imapMessageFlagsType flags = m_flagState->GetMessageFlagsFromUID(uid, &foundIt, &index); @@ -2259,7 +2257,7 @@ void nsImapProtocol::ProcessSelectedStateURL() break; case nsIImapUrl::nsImapMsgHeader: { - nsXPIDLCString messageIds; + nsCString messageIds; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIds)); // we don't want to send the flags back in a group @@ -2275,27 +2273,27 @@ void nsImapProtocol::ProcessSelectedStateURL() break; case nsIImapUrl::nsImapSearch: { - nsXPIDLCString searchCriteriaString; + nsCAutoString searchCriteriaString; m_runningUrl->CreateSearchCriteriaString(getter_Copies(searchCriteriaString)); - Search(searchCriteriaString, bMessageIdsAreUids); + Search(searchCriteriaString.get(), bMessageIdsAreUids); // drop the results on the floor for now } break; case nsIImapUrl::nsImapUserDefinedMsgCommand: { - nsXPIDLCString messageIdString; - nsXPIDLCString command; - + nsCString messageIdString; + nsCString command; + m_runningUrl->GetCommand(getter_Copies(command)); m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); - IssueUserDefinedMsgCommand(command, messageIdString); + IssueUserDefinedMsgCommand(command.get(), messageIdString.get()); } break; case nsIImapUrl::nsImapUserDefinedFetchAttribute: { - nsXPIDLCString messageIdString; - nsXPIDLCString attribute; - + nsCString messageIdString; + nsCString attribute; + m_runningUrl->GetCustomAttributeToFetch(getter_Copies(attribute)); m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); FetchMsgAttribute(messageIdString, attribute); @@ -2308,10 +2306,10 @@ void nsImapProtocol::ProcessSelectedStateURL() GetSupportedUserFlags(&userFlags); if (! (userFlags & kImapMsgSupportUserFlag)) break; - nsXPIDLCString messageIdString; - nsXPIDLCString addFlags; - nsXPIDLCString subtractFlags; - + nsCString messageIdString; + nsCString addFlags; + nsCString subtractFlags; + m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); m_runningUrl->GetCustomAddFlags(getter_Copies(addFlags)); m_runningUrl->GetCustomSubtractFlags(getter_Copies(subtractFlags)); @@ -2333,14 +2331,12 @@ void nsImapProtocol::ProcessSelectedStateURL() break; case nsIImapUrl::nsImapDeleteMsg: { - nsXPIDLCString messageIdString; - + nsCString messageIdString; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); - if (HandlingMultipleMessages(messageIdString)) - ProgressEventFunctionUsingId (IMAP_DELETING_MESSAGES); - else - ProgressEventFunctionUsingId(IMAP_DELETING_MESSAGE); - + + ProgressEventFunctionUsingId (HandlingMultipleMessages(messageIdString) ? + IMAP_DELETING_MESSAGES :IMAP_DELETING_MESSAGE); + Store(messageIdString, "+FLAGS (\\Deleted)", bMessageIdsAreUids); if (GetServerStateParser().LastCommandSuccessful()) @@ -2360,7 +2356,7 @@ void nsImapProtocol::ProcessSelectedStateURL() } if (m_imapMessageSink) - m_imapMessageSink->NotifyMessageDeleted(canonicalName, PR_FALSE, messageIdString); + m_imapMessageSink->NotifyMessageDeleted(canonicalName, PR_FALSE, messageIdString.get()); // notice we don't wait for this to finish... } else @@ -2368,17 +2364,16 @@ void nsImapProtocol::ProcessSelectedStateURL() } break; case nsIImapUrl::nsImapDeleteFolderAndMsgs: - DeleteFolderAndMsgs(mailboxName); + DeleteFolderAndMsgs(mailboxName.get()); break; case nsIImapUrl::nsImapDeleteAllMsgs: { uint32 numberOfMessages = GetServerStateParser().NumberOfMessages(); if (numberOfMessages) { - - Store("1:*", "+FLAGS.SILENT (\\Deleted)", - PR_FALSE); // use sequence #'s - + Store(NS_LITERAL_CSTRING("1:*"), "+FLAGS.SILENT (\\Deleted)", + PR_FALSE); // use sequence #'s + if (GetServerStateParser().LastCommandSuccessful()) Expunge(); // expunge messages with deleted flag if (GetServerStateParser().LastCommandSuccessful()) @@ -2402,7 +2397,7 @@ void nsImapProtocol::ProcessSelectedStateURL() } PRBool deleteSelf = PR_FALSE; - DeleteSubFolders(mailboxName, deleteSelf); // don't delete self + DeleteSubFolders(mailboxName.get(), deleteSelf); // don't delete self } break; case nsIImapUrl::nsImapAppendDraftFromFile: @@ -2412,7 +2407,7 @@ void nsImapProtocol::ProcessSelectedStateURL() break; case nsIImapUrl::nsImapAddMsgFlags: { - nsXPIDLCString messageIdString; + nsCString messageIdString; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); ProcessStoreFlags(messageIdString, bMessageIdsAreUids, @@ -2421,7 +2416,7 @@ void nsImapProtocol::ProcessSelectedStateURL() break; case nsIImapUrl::nsImapSubtractMsgFlags: { - nsXPIDLCString messageIdString; + nsCString messageIdString; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); ProcessStoreFlags(messageIdString, bMessageIdsAreUids, @@ -2430,7 +2425,7 @@ void nsImapProtocol::ProcessSelectedStateURL() break; case nsIImapUrl::nsImapSetMsgFlags: { - nsXPIDLCString messageIdString; + nsCString messageIdString; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); ProcessStoreFlags(messageIdString, bMessageIdsAreUids, @@ -2445,7 +2440,7 @@ void nsImapProtocol::ProcessSelectedStateURL() case nsIImapUrl::nsImapOnlineCopy: case nsIImapUrl::nsImapOnlineMove: { - nsXPIDLCString messageIdString; + nsCString messageIdString; m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); char *destinationMailbox = OnCreateServerDestinationFolderPathString(); @@ -2464,8 +2459,7 @@ void nsImapProtocol::ProcessSelectedStateURL() else ProgressEventFunctionUsingIdWithString (IMAP_COPYING_MESSAGE_TO, destinationMailbox); } - - Copy(messageIdString, destinationMailbox, bMessageIdsAreUids); + Copy(messageIdString.get(), destinationMailbox, bMessageIdsAreUids); PR_FREEIF( destinationMailbox); ImapOnlineCopyState copyState; if (DeathSignalReceived()) @@ -2504,26 +2498,23 @@ void nsImapProtocol::ProcessSelectedStateURL() case nsIImapUrl::nsImapOnlineToOfflineCopy: case nsIImapUrl::nsImapOnlineToOfflineMove: { - nsXPIDLCString messageIdString; + nsCString messageIdString; nsresult rv = m_runningUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); if (NS_SUCCEEDED(rv)) { SetProgressString(IMAP_FOLDER_RECEIVING_MESSAGE_OF); m_progressIndex = 0; - m_progressCount = CountMessagesInIdString(messageIdString); - - FetchMessage(messageIdString, - kEveryThingRFC822Peek, - bMessageIdsAreUids); + m_progressCount = CountMessagesInIdString(messageIdString.get()); + + FetchMessage(messageIdString, kEveryThingRFC822Peek, bMessageIdsAreUids); SetProgressString(0); if (m_imapMailFolderSink) { ImapOnlineCopyState copyStatus; - if (GetServerStateParser().LastCommandSuccessful()) - copyStatus = ImapOnlineCopyStateType::kSuccessfulCopy; - else - copyStatus = ImapOnlineCopyStateType::kFailedCopy; + copyStatus = GetServerStateParser().LastCommandSuccessful() ? + ImapOnlineCopyStateType::kSuccessfulCopy : ImapOnlineCopyStateType::kFailedCopy; + m_imapMailFolderSink->OnlineCopyCompleted(this, copyStatus); if (GetServerStateParser().LastCommandSuccessful() && (m_imapAction == nsIImapUrl::nsImapOnlineToOfflineMove)) @@ -2772,7 +2763,7 @@ void nsImapProtocol::SelectMailbox(const char *mailboxName) } // Please call only with a single message ID -void nsImapProtocol::Bodystructure(const char *messageId, PRBool idIsUid) +void nsImapProtocol::Bodystructure(const nsCString &messageId, PRBool idIsUid) { IncrementCommandTagNumber(); @@ -2855,7 +2846,7 @@ void nsImapProtocol::PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePa } -void nsImapProtocol::FetchMsgAttribute(const char * messageIds, const char *attribute) +void nsImapProtocol::FetchMsgAttribute(const nsCString &messageIds, const nsCString &attribute) { IncrementCommandTagNumber(); @@ -2876,7 +2867,7 @@ void nsImapProtocol::FetchMsgAttribute(const char * messageIds, const char *attr // this routine is used to fetch a message or messages, or headers for a // message... -void nsImapProtocol::FallbackToFetchWholeMsg(const char *messageId, PRUint32 messageSize) +void nsImapProtocol::FallbackToFetchWholeMsg(const nsCString &messageId, PRUint32 messageSize) { if (m_imapMessageSink && m_runningUrl) { @@ -2889,7 +2880,7 @@ void nsImapProtocol::FallbackToFetchWholeMsg(const char *messageId, PRUint32 mes } void -nsImapProtocol::FetchMessage(const char * messageIds, +nsImapProtocol::FetchMessage(const nsCString &messageIds, nsIMAPeFetchFields whatToFetch, PRBool idIsUid, PRUint32 startByte, PRUint32 endByte, @@ -2989,7 +2980,7 @@ nsImapProtocol::FetchMessage(const char * messageIds, char *headersToDL = nsnull; char *what = nsnull; const char *dbHeaders = (gUseEnvelopeCmd) ? IMAP_DB_HEADERS : IMAP_ENV_AND_DB_HEADERS; - nsXPIDLCString arbitraryHeaders; + nsCString arbitraryHeaders; GetArbitraryHeadersToDownload(getter_Copies(arbitraryHeaders)); for (PRInt32 i = 0; i < gCustomDBHeaders.Count(); i++) { @@ -3001,7 +2992,7 @@ nsImapProtocol::FetchMessage(const char * messageIds, } } if (arbitraryHeaders.IsEmpty()) - headersToDL = nsCRT::strdup(dbHeaders); + headersToDL = strdup(dbHeaders); else headersToDL = PR_smprintf("%s %s",dbHeaders, arbitraryHeaders.get()); @@ -3099,7 +3090,7 @@ nsImapProtocol::FetchMessage(const char * messageIds, // since messageIds can be infinitely long, use a dynamic buffer rather than the fixed one const char *commandTag = GetServerCommandTag(); - int protocolStringSize = commandString.Length() + strlen(messageIds) + PL_strlen(commandTag) + 1 + + int protocolStringSize = commandString.Length() + messageIds.Length() + PL_strlen(commandTag) + 1 + (part ? PL_strlen(part) : 0); char *protocolString = (char *) PR_CALLOC( protocolStringSize ); @@ -3113,7 +3104,7 @@ nsImapProtocol::FetchMessage(const char * messageIds, protocolStringSize, // max size cCommandStr, // format string commandTag, // command tag - messageIds, + messageIds.get(), part); } else @@ -3122,7 +3113,7 @@ nsImapProtocol::FetchMessage(const char * messageIds, protocolStringSize, // max size cCommandStr, // format string commandTag, // command tag - messageIds); + messageIds.get()); } nsresult rv = SendData(protocolString); @@ -3140,7 +3131,7 @@ nsImapProtocol::FetchMessage(const char * messageIds, HandleMemoryFailure(); } -void nsImapProtocol::FetchTryChunking(const char * messageIds, +void nsImapProtocol::FetchTryChunking(const nsCString &messageIds, nsIMAPeFetchFields whatToFetch, PRBool idIsUid, char *part, @@ -3602,7 +3593,7 @@ void nsImapProtocol::ProcessMailboxUpdate(PRBool handlePossibleUndo) if (handlePossibleUndo) { // undo any delete flags we may have asked to - nsXPIDLCString undoIdsStr; + nsCString undoIdsStr; nsCAutoString undoIds; GetCurrentUrl()->CreateListOfMessageIdsString(getter_Copies(undoIdsStr)); @@ -3614,10 +3605,10 @@ void nsImapProtocol::ProcessMailboxUpdate(PRBool handlePossibleUndo) // if this string started with a '-', then this is an undo of a delete // if its a '+' its a redo if (firstChar == '-') - Store(undoIds.get(), "-FLAGS (\\Deleted)", PR_TRUE); // most servers will fail silently on a failure, deal with it? + Store(undoIds, "-FLAGS (\\Deleted)", PR_TRUE); // most servers will fail silently on a failure, deal with it? else if (firstChar == '+') - Store(undoIds.get(), "+FLAGS (\\Deleted)", PR_TRUE); // most servers will fail silently on a failure, deal with it? - else + Store(undoIds, "+FLAGS (\\Deleted)", PR_TRUE); // most servers will fail silently on a failure, deal with it? + else NS_ASSERTION(PR_FALSE, "bogus undo Id's"); } } @@ -3632,7 +3623,7 @@ void nsImapProtocol::ProcessMailboxUpdate(PRBool handlePossibleUndo) if (!added || (added == deleted)) { nsCString idsToFetch("1:*"); - FetchMessage(idsToFetch.get(), kFlags, PR_TRUE); // id string shows uids + FetchMessage(idsToFetch, kFlags, PR_TRUE); // id string shows uids // lets see if we should expunge during a full sync of flags. if (!DeathSignalReceived()) // only expunge if not reading messages manually and before fetching new { @@ -3650,7 +3641,7 @@ void nsImapProtocol::ProcessMailboxUpdate(PRBool handlePossibleUndo) fetchStr.Append(":*"); // sprintf(fetchStr, "%ld:*", GetServerStateParser().HighestRecordedUID() + 1); - FetchMessage(fetchStr.get(), kFlags, PR_TRUE); // only new messages please + FetchMessage(fetchStr, kFlags, PR_TRUE); // only new messages please } } else if (!DeathSignalReceived()) @@ -3849,7 +3840,7 @@ void nsImapProtocol::FolderMsgDumpLoop(PRUint32 *msgUids, PRUint32 msgCount, nsI PRUint32 msgsToDownload = msgCountLeft; AllocateImapUidString(msgUids + msgsDownloaded, msgsToDownload, m_flagState, idString); // 20 * 200 - FetchMessage(idString.get(), fields, PR_TRUE); // msg ids are uids + FetchMessage(idString, fields, PR_TRUE); // msg ids are uids msgsDownloaded += msgsToDownload; msgCountLeft -= msgsToDownload; @@ -3899,9 +3890,8 @@ void nsImapProtocol::PeriodicBiff() //sprintf(fetchStr, "%ld:%ld", id, id + GetServerStateParser().NumberOfMessages() - fFlagState->GetNumberOfMessages()); fetchStr.AppendInt(id); - fetchStr.Append(":*"); - FetchMessage(fetchStr.get(), kFlags, PR_TRUE); - + fetchStr.Append(":*"); + FetchMessage(fetchStr, kFlags, PR_TRUE); if (((PRUint32) m_flagState->GetHighestNonDeletedUID() >= id) && m_flagState->IsLastMessageUnseen()) m_currentBiffState = nsIMsgFolder::nsMsgBiffState_NewMail; else @@ -4009,9 +3999,9 @@ void nsImapProtocol::Log(const char *logSubName, const char *extraInfo, const ch } if (extraInfo) - PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s:%s:%s: %.400s", this,hostName,stateName,logSubName,extraInfo,logDataToLog)); + PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s:%s:%s: %.400s", this,hostName.get(),stateName,logSubName,extraInfo,logDataToLog)); else - PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s:%s: %.400s",this,hostName,stateName,logSubName,logDataToLog)); + PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s:%s: %.400s",this,hostName.get(),stateName,logSubName,logDataToLog)); // dump the rest of the string in < 400 byte chunks while (logDataLen > kLogDataChunkSize) @@ -4075,10 +4065,9 @@ PRUint32 nsImapProtocol::GetMessageSize(const char * messageId, } // message id string utility functions -/* static */PRBool nsImapProtocol::HandlingMultipleMessages(const char *messageIdString) +/* static */PRBool nsImapProtocol::HandlingMultipleMessages(const nsCString & messageIdString) { - return (PL_strchr(messageIdString,',') != nsnull || - PL_strchr(messageIdString,':') != nsnull); + return (messageIdString.FindCharInSet(",:") != kNotFound); } PRUint32 nsImapProtocol::CountMessagesInIdString(const char *idString) @@ -4715,16 +4704,14 @@ nsImapProtocol::ShowProgress() PRUnichar *progressString = NULL; nsCAutoString cProgressString; cProgressString.AssignWithConversion(m_progressString); const char *mailboxName = GetServerStateParser().GetSelectedMailboxName(); - - nsXPIDLString unicodeMailboxName; - + nsString unicodeMailboxName; nsresult rv = CopyMUTF7toUTF16(nsDependentCString(mailboxName), unicodeMailboxName); if (NS_SUCCEEDED(rv)) { // ### should convert mailboxName to PRUnichar and change %s to %S in msg text - progressString = nsTextFormatter::smprintf(m_progressString.get(), (const PRUnichar *) unicodeMailboxName, - ++m_progressIndex, m_progressCount); + progressString = nsTextFormatter::smprintf(m_progressString.get(), + unicodeMailboxName.get(), ++m_progressIndex, m_progressCount); if (progressString) { PercentProgressUpdateEvent(progressString, m_progressIndex, m_progressCount); @@ -4751,10 +4738,10 @@ nsImapProtocol::ProgressEventFunctionUsingIdWithString(PRUint32 aMsgId, const { if (m_imapMailFolderSink) { - nsXPIDLString unicodeStr; + nsString unicodeStr; nsresult rv = CopyMUTF7toUTF16(nsDependentCString(aExtraInfo), unicodeStr); if (NS_SUCCEEDED(rv)) - m_imapMailFolderSink->ProgressStatus(this, aMsgId, unicodeStr); + m_imapMailFolderSink->ProgressStatus(this, aMsgId, unicodeStr.get()); } } @@ -4794,7 +4781,7 @@ nsImapProtocol::PercentProgressUpdateEvent(PRUnichar *message, PRInt32 currentPr // imap commands issued by the parser void -nsImapProtocol::Store(const char * messageList, const char * messageData, +nsImapProtocol::Store(const nsCString &messageList, const char * messageData, PRBool idsAreUid) { @@ -4803,7 +4790,7 @@ nsImapProtocol::Store(const char * messageList, const char * messageData, nsCString messageIdList; nsMsgKeyArray msgKeys; if (idsAreUid) - ParseUidString(messageList, msgKeys); + ParseUidString(messageList.get(), msgKeys); PRInt32 msgCountLeft = msgKeys.GetSize(); PRUint32 msgsHandled = 0; @@ -4834,7 +4821,7 @@ nsImapProtocol::Store(const char * messageList, const char * messageData, const char *commandTag = GetServerCommandTag(); int protocolStringSize = PL_strlen(formatString) + - PL_strlen(messageList) + PL_strlen(messageData) + + messageList.Length() + PL_strlen(messageData) + PL_strlen(commandTag) + 1; char *protocolString = (char *) PR_CALLOC( protocolStringSize ); @@ -4897,7 +4884,7 @@ nsImapProtocol::IssueUserDefinedMsgCommand(const char *command, const char * mes } void -nsImapProtocol::UidExpunge(const char* messageSet) +nsImapProtocol::UidExpunge(const nsCString &messageSet) { IncrementCommandTagNumber(); nsCString command(GetServerCommandTag()); @@ -5069,7 +5056,7 @@ void nsImapProtocol::EscapeUserNamePasswordString(const char *strToEscape, nsCSt } } -void nsImapProtocol::InsecureLogin(const char *userName, const char *password) +void nsImapProtocol::InsecureLogin(const char *userName, const nsCString &password) { ProgressEventFunctionUsingId (IMAP_STATUS_SENDING_LOGIN); IncrementCommandTagNumber(); @@ -5083,7 +5070,7 @@ void nsImapProtocol::InsecureLogin(const char *userName, const char *password) // if the password contains a \, login will fail // turn foo\bar into foo\\bar nsCAutoString correctedPassword; - EscapeUserNamePasswordString(password, &correctedPassword); + EscapeUserNamePasswordString(password.get(), &correctedPassword); command.Append(correctedPassword); command.Append("\""CRLF); @@ -5093,7 +5080,7 @@ void nsImapProtocol::InsecureLogin(const char *userName, const char *password) ParseIMAPandCheckForNewMail(); } -nsresult nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag) +nsresult nsImapProtocol::AuthLogin(const char *userName, const nsCString &password, eIMAPCapabilityFlag flag) { ProgressEventFunctionUsingId (IMAP_STATUS_SENDING_AUTH_LOGIN); IncrementCommandTagNumber(); @@ -5115,7 +5102,7 @@ nsresult nsImapProtocol::AuthLogin(const char *userName, const char *password, e char * decodedChallenge = PL_Base64Decode(cramDigest, strlen(cramDigest), nsnull); if (m_imapServerSink) - rv = m_imapServerSink->CramMD5Hash(decodedChallenge, password, &digest); + rv = m_imapServerSink->CramMD5Hash(decodedChallenge, password.get(), &digest); PR_Free(decodedChallenge); if (NS_SUCCEEDED(rv) && digest) @@ -5203,7 +5190,7 @@ nsresult nsImapProtocol::AuthLogin(const char *userName, const char *password, e if (GetServerStateParser().LastCommandSuccessful()) { nsCAutoString cmd; - rv = DoNtlmStep1(userName, password, cmd); + rv = DoNtlmStep1(userName, password.get(), cmd); if (NS_SUCCEEDED(rv)) { cmd += CRLF; @@ -5244,9 +5231,8 @@ nsresult nsImapProtocol::AuthLogin(const char *userName, const char *password, e PR_snprintf(&plainstr[1], 510, "%s", userName); len += PL_strlen(userName); len++; // count for second char - PR_snprintf(&plainstr[len], 511-len, "%s", password); - len += PL_strlen(password); - + PR_snprintf(&plainstr[len], 511-len, "%s", password.get()); + len += password.Length(); char *base64Str = PL_Base64Encode(plainstr, len, nsnull); if (base64Str) { @@ -5285,7 +5271,7 @@ nsresult nsImapProtocol::AuthLogin(const char *userName, const char *password, e } if (GetServerStateParser().LastCommandSuccessful()) { - base64Str = PL_Base64Encode((char*)password, PL_strlen(password), nsnull); + base64Str = PL_Base64Encode(password.get(), password.Length(), nsnull); PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str); PR_Free(base64Str); rv = SendData(m_dataOutputBuf, PR_TRUE /* suppress logging */); @@ -5346,7 +5332,7 @@ void nsImapProtocol::OnAppendMsgFromFile() imapMessageFlagsType flagsToSet = 0; PRUint32 msgFlags = 0; PRTime date = 0; - nsXPIDLCString keywords; + nsCString keywords; if (m_imapMessageSink) m_imapMessageSink->GetCurMoveCopyMessageInfo(m_runningUrl, &date, getter_Copies(keywords), &msgFlags); @@ -5510,7 +5496,7 @@ void nsImapProtocol::UploadMessageFromFile (nsIFile* file, if (FolderIsSelected(mailboxName)) Noop(); - nsXPIDLCString oldMsgId; + nsCString oldMsgId; rv = m_runningUrl->CreateListOfMessageIdsString(getter_Copies(oldMsgId)); if (NS_SUCCEEDED(rv) && !oldMsgId.IsEmpty()) { @@ -5673,7 +5659,7 @@ void nsImapProtocol::OnEnsureExistsFolder(const char * aSourceMailbox) aSourceMailbox, nsForMailbox); // NS_ASSERTION (nsForMailbox, "Oops .. null nsForMailbox\n"); - nsXPIDLCString name; + nsCString name; if (nsForMailbox) m_runningUrl->AllocateCanonicalPath(aSourceMailbox, @@ -5784,7 +5770,7 @@ void nsImapProtocol::RefreshACLForFolder(const char *mailboxName) void nsImapProtocol::RefreshFolderACLView(const char *mailboxName, nsIMAPNamespace *nsForMailbox) { - nsXPIDLCString canonicalMailboxName; + nsCString canonicalMailboxName; if (nsForMailbox) m_runningUrl->AllocateCanonicalPath(mailboxName, nsForMailbox->GetDelimiter(), getter_Copies(canonicalMailboxName)); @@ -6443,7 +6429,7 @@ void nsImapProtocol::RemoveMsgsAndExpunge() if (numberOfMessages) { // Remove all msgs and expunge the folder (ie, compact it). - Store("1:*", "+FLAGS.SILENT (\\Deleted)", PR_FALSE); // use sequence #'s + Store(NS_LITERAL_CSTRING("1:*"), "+FLAGS.SILENT (\\Deleted)", PR_FALSE); // use sequence #'s if (GetServerStateParser().LastCommandSuccessful()) Expunge(); } @@ -7005,7 +6991,7 @@ const char * nsImapProtocol::GetTrashFolderName() nsCOMPtr server = do_QueryReferent(m_server); if (server) { - nsString trashFolderName; + nsAutoString trashFolderName; if (NS_SUCCEEDED(server->GetTrashFolderName(trashFolderName))) CopyUTF16toMUTF7(trashFolderName, m_trashFolderName); } @@ -7456,7 +7442,7 @@ void nsImapProtocol::SetupMessageFlagsString(nsCString& flagString, flagString.SetLength(flagString.Length()-1); } -void nsImapProtocol::ProcessStoreFlags(const char * messageIdsString, +void nsImapProtocol::ProcessStoreFlags(const nsCString &messageIdsString, PRBool idsAreUids, imapMessageFlagsType flags, PRBool addFlags) @@ -7608,8 +7594,8 @@ PRBool nsImapProtocol::TryToLogon() PRInt32 logonTries = 0; PRBool loginSucceeded = PR_FALSE; PRBool clientSucceeded = PR_TRUE; - nsCString password; - nsCString userName; + nsCAutoString password; + nsCAutoString userName; nsresult rv = NS_OK; // get the password and user name for the current incoming server... @@ -7687,38 +7673,38 @@ PRBool nsImapProtocol::TryToLogon() // all subsequent login attempts to fail (bug 231303, bug 227560) if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthGssApiCapability) { - clientSucceeded = NS_SUCCEEDED(AuthLogin(userName.get(), password.get(), kHasAuthGssApiCapability)); + clientSucceeded = NS_SUCCEEDED(AuthLogin(userName.get(), password, kHasAuthGssApiCapability)); } else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasCRAMCapability) { - AuthLogin (userName.get(), password.get(), kHasCRAMCapability); + AuthLogin (userName.get(), password, kHasCRAMCapability); logonTries++; } else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthNTLMCapability) { - AuthLogin (userName.get(), password.get(), kHasAuthNTLMCapability); + AuthLogin (userName.get(), password, kHasAuthNTLMCapability); logonTries++; } else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthMSNCapability) { - AuthLogin (userName.get(), password.get(), kHasAuthMSNCapability); + AuthLogin (userName.get(), password, kHasAuthMSNCapability); logonTries++; } else if (GetServerStateParser().GetCapabilityFlag() & kHasAuthPlainCapability) { - AuthLogin (userName.get(), password.get(), kHasAuthPlainCapability); + AuthLogin (userName.get(), password, kHasAuthPlainCapability); logonTries++; } else if (GetServerStateParser().GetCapabilityFlag() & kHasAuthLoginCapability) { - AuthLogin (userName.get(), password.get(), kHasAuthLoginCapability); + AuthLogin (userName.get(), password, kHasAuthLoginCapability); logonTries++; // This counts as a logon try for most servers } else if (! (GetServerStateParser().GetCapabilityFlag() & kLoginDisabled)) - InsecureLogin(userName.get(), password.get()); + InsecureLogin(userName.get(), password); } else if (! (GetServerStateParser().GetCapabilityFlag() & kLoginDisabled)) - InsecureLogin(userName.get(), password.get()); + InsecureLogin(userName.get(), password); if (!clientSucceeded || !GetServerStateParser().LastCommandSuccessful()) { @@ -7815,7 +7801,7 @@ void nsImapProtocol::GetQuotaDataIfSupported(const char *aBoxName) nsCOMPtr imapServer = do_QueryReferent(m_server, &rv); if (NS_FAILED(rv)) return; - nsCString redirectorType; + nsCAutoString redirectorType; imapServer->GetRedirectorType(redirectorType); if (redirectorType.EqualsLiteral("aol") && PL_strcasecmp("Inbox", aBoxName)) return; @@ -8312,9 +8298,9 @@ nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntryDescriptor *entry) NS_ENSURE_ARG(entry); PRUint32 annotationLength = 0; - nsXPIDLCString annotation; + nsCString annotation; nsCAutoString entryKey; - nsXPIDLCString contentType; + nsCAutoString contentType; nsresult rv = NS_OK; PRBool shouldUseCacheEntry = PR_FALSE; @@ -8331,12 +8317,9 @@ nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntryDescriptor *entry) { // otherwise, we have the whole msg, and we should make sure the content isn't modified. rv = entry->GetMetaDataElement("ContentModified", getter_Copies(annotation)); - if (NS_SUCCEEDED(rv) && (annotation.get())) - { - annotationLength = strlen(annotation.get()); - if (annotationLength == strlen("Not Modified") && !nsCRT::strncmp(annotation, "Not Modified", annotationLength)) - shouldUseCacheEntry = PR_TRUE; - } + if (NS_SUCCEEDED(rv) && !annotation.IsEmpty()) + shouldUseCacheEntry = annotation.EqualsLiteral("Not Modified"); + } if (shouldUseCacheEntry) { @@ -8423,7 +8406,7 @@ PRBool nsImapMockChannel::ReadFromLocalCache() mailnewsUrl->GetMsgIsInLocalCache(&useLocalCache); if (useLocalCache) { - nsXPIDLCString messageIdString; + nsCAutoString messageIdString; SetupPartExtractorListener(imapUrl, m_channelListener); @@ -8434,7 +8417,7 @@ PRBool nsImapMockChannel::ReadFromLocalCache() { // we want to create a file channel and read the msg from there. nsCOMPtr fileStream; - nsMsgKey msgKey = atoi(messageIdString); + nsMsgKey msgKey = atoi(messageIdString.get()); PRUint32 size, offset; rv = folder->GetOfflineFileStream(msgKey, &offset, &size, getter_AddRefs(fileStream)); // get the file channel from the folder, somehow (through the message or diff --git a/mailnews/imap/src/nsImapProtocol.h b/mailnews/imap/src/nsImapProtocol.h index 363ab22d643..21fa1db2e39 100644 --- a/mailnews/imap/src/nsImapProtocol.h +++ b/mailnews/imap/src/nsImapProtocol.h @@ -78,7 +78,6 @@ #include "nsILoadGroup.h" #include "nsCOMPtr.h" #include "nsIImapIncomingServer.h" -#include "nsXPIDLString.h" #include "nsIMsgWindow.h" #include "nsIMsgLogonRedirector.h" #include "nsICacheListener.h" @@ -175,8 +174,7 @@ public: // message id string utilities. PRUint32 CountMessagesInIdString(const char *idString); - static PRBool HandlingMultipleMessages(const char *messageIdString); - + static PRBool HandlingMultipleMessages(const nsCString &messageIdString); // escape slashes and double quotes in username/passwords for insecure login. static void EscapeUserNamePasswordString(const char *strToEscape, nsCString *resultStr); @@ -184,20 +182,19 @@ public: void GetShouldDownloadAllHeaders(PRBool *aResult); void GetArbitraryHeadersToDownload(char **aResult); virtual void AdjustChunkSize(); - virtual void FetchMessage(const char * messageIds, + virtual void FetchMessage(const nsCString &messageIds, nsIMAPeFetchFields whatToFetch, PRBool idAreUid, PRUint32 startByte = 0, PRUint32 endByte = 0, char *part = 0); - void FetchTryChunking(const char * messageIds, + void FetchTryChunking(const nsCString &messageIds, nsIMAPeFetchFields whatToFetch, PRBool idIsUid, char *part, PRUint32 downloadSize, PRBool tryChunking); virtual void PipelinedFetchMessageParts(nsCString &uid, nsIMAPMessagePartIDArray *parts); - void FallbackToFetchWholeMsg(const char *messageId, PRUint32 messageSize); - + void FallbackToFetchWholeMsg(const nsCString &messageId, PRUint32 messageSize); // used when streaming a message fetch virtual nsresult BeginMessageDownLoad(PRUint32 totalSize, // for user, headers and body const char *contentType); // some downloads are header only @@ -266,16 +263,16 @@ public: void Search(const char * searchCriteria, PRBool useUID, PRBool notifyHit = PR_TRUE); // imap commands issued by the parser - void Store(const char * aMessageList, const char * aMessageData, PRBool + void Store(const nsCString &aMessageList, const char * aMessageData, PRBool aIdsAreUid); - void ProcessStoreFlags(const char * messageIds, + void ProcessStoreFlags(const nsCString &messageIds, PRBool idsAreUids, imapMessageFlagsType flags, PRBool addFlags); void IssueUserDefinedMsgCommand(const char *command, const char * messageList); - void FetchMsgAttribute(const char * messageIds, const char *attribute); + void FetchMsgAttribute(const nsCString &messageIds, const nsCString &attribute); void Expunge(); - void UidExpunge(const char* messageSet); + void UidExpunge(const nsCString &messageSet); void Close(PRBool shuttingDown = PR_FALSE, PRBool waitForResponse = PR_TRUE); void Check(); void SelectMailbox(const char *mailboxName); @@ -289,7 +286,7 @@ public: void MailboxData(); void GetMyRightsForFolder(const char *mailboxName); void AutoSubscribeToMailboxIfNecessary(const char *mailboxName); - void Bodystructure(const char *messageId, PRBool idIsUid); + void Bodystructure(const nsCString &messageId, PRBool idIsUid); void PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePartIDArray *parts); @@ -458,8 +455,8 @@ private: void Capability(); // query host for capabilities. void Language(); // set the language on the server if it supports it void Namespace(); - void InsecureLogin(const char *userName, const char *password); - nsresult AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag); + void InsecureLogin(const char *userName, const nsCString &password); + nsresult AuthLogin(const char *userName, const nsCString &password, eIMAPCapabilityFlag flag); void ProcessAuthenticatedStateURL(); void ProcessAfterAuthenticated(); void ProcessSelectedStateURL(); @@ -570,12 +567,12 @@ private: nsCString m_logonHost; nsCString m_logonCookie; PRInt16 m_logonPort; - - nsXPIDLString mAcceptLanguages; - + + nsString mAcceptLanguages; + // progress stuff void SetProgressString(PRInt32 stringId); - + nsString m_progressString; PRInt32 m_progressStringId; PRInt32 m_progressIndex; diff --git a/mailnews/imap/src/nsImapServerResponseParser.cpp b/mailnews/imap/src/nsImapServerResponseParser.cpp index 807378e5e0f..d2d8ecfb603 100644 --- a/mailnews/imap/src/nsImapServerResponseParser.cpp +++ b/mailnews/imap/src/nsImapServerResponseParser.cpp @@ -444,7 +444,7 @@ void nsImapServerResponseParser::ProcessOkCommand(const char *commandToken) if (!fZeroLengthMessageUidString.IsEmpty()) { // "Deleting zero length message"); - fServerConnection.Store(fZeroLengthMessageUidString.get(), "+Flags (\\Deleted)", PR_TRUE); + fServerConnection.Store(fZeroLengthMessageUidString, "+Flags (\\Deleted)", PR_TRUE); if (LastCommandSuccessful()) fServerConnection.Expunge(); @@ -722,7 +722,7 @@ void nsImapServerResponseParser::response_data() else { // check if custom command - nsXPIDLCString customCommand; + nsCAutoString customCommand; fServerConnection.GetCurrentUrl()->GetCommand(getter_Copies(customCommand)); if (customCommand.Equals(fNextToken)) { @@ -1298,7 +1298,7 @@ void nsImapServerResponseParser::msg_fetch() if (!fServerConnection.GetCurrentUrl()) return; fServerConnection.GetCurrentUrl()->GetImapAction(&imapAction); - nsXPIDLCString userDefinedFetchAttribute; + nsCAutoString userDefinedFetchAttribute; fServerConnection.GetCurrentUrl()->GetCustomAttributeToFetch(getter_Copies(userDefinedFetchAttribute)); if (imapAction == nsIImapUrl::nsImapUserDefinedFetchAttribute && !strcmp(userDefinedFetchAttribute.get(), fNextToken)) { @@ -1407,12 +1407,10 @@ void nsImapServerResponseParser::envelope_data() PRBool headerNonNil = PR_TRUE; if (EnvelopeTable[tableIndex].type == envelopeString) { - nsXPIDLCString strValue; + nsCAutoString strValue; strValue.Adopt(CreateNilString()); - if (strValue) - { + if (!strValue.IsEmpty()) headerLine.Append(strValue); - } else headerNonNil = PR_FALSE; } @@ -1444,7 +1442,7 @@ void nsImapServerResponseParser::xaolenvelope_data() { AdvanceToNextToken(); fNextToken++; // eat '(' - nsXPIDLCString subject; + nsCAutoString subject; subject.Adopt(CreateNilString()); nsCAutoString subjectLine("Subject: "); subjectLine += subject; diff --git a/mailnews/imap/src/nsImapService.cpp b/mailnews/imap/src/nsImapService.cpp index bb6c4f5291e..de6154e67a8 100644 --- a/mailnews/imap/src/nsImapService.cpp +++ b/mailnews/imap/src/nsImapService.cpp @@ -57,7 +57,6 @@ #include "nsIDocShell.h" #include "nsIDocShellLoadInfo.h" #include "nsIRDFService.h" -#include "nsXPIDLString.h" #include "nsReadableUtils.h" #include "nsRDFCID.h" #include "nsEscape.h" @@ -166,7 +165,7 @@ nsImapService::GetFolderName(nsIMsgFolder* aImapFolder, nsresult rv; nsCOMPtr aFolder(do_QueryInterface(aImapFolder, &rv)); if (NS_FAILED(rv)) return rv; - nsXPIDLCString onlineName; + nsCString onlineName; // online name is in imap utf-7 - leave it that way rv = aFolder->GetOnlineName(getter_Copies(onlineName)); @@ -187,15 +186,15 @@ nsImapService::GetFolderName(nsIMsgFolder* aImapFolder, // otherwise, we do want to escape slashes. // we want to escape slashes and '^' first, otherwise, nsEscape will lose them PRBool escapeSlashes = (GetHierarchyDelimiter(aImapFolder) != (PRUnichar) '/'); - if (escapeSlashes && (const char *) onlineName) + if (escapeSlashes && !onlineName.IsEmpty()) { char* escapedOnlineName; - rv = nsImapUrl::EscapeSlashes((const char *) onlineName, &escapedOnlineName); + rv = nsImapUrl::EscapeSlashes(onlineName.get(), &escapedOnlineName); if (NS_SUCCEEDED(rv)) onlineName.Adopt(escapedOnlineName); } // need to escape everything else - *folderName = nsEscape((const char *) onlineName, url_Path); + *folderName = nsEscape(onlineName.get(), url_Path); return rv; } @@ -244,11 +243,11 @@ nsImapService::SelectFolder(nsIEventTarget * aClientEventTarget, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); urlSpec.Append("/select>"); urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); rv = mailNewsUrl->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) rv = GetImapConnectionAndLoadUrl(aClientEventTarget, @@ -282,7 +281,7 @@ NS_IMETHODIMP nsImapService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL nsCOMPtr folder; - nsXPIDLCString msgKey; + nsCAutoString msgKey; rv = DecomposeImapURI(aMessageURI, getter_AddRefs(folder), getter_Copies(msgKey)); if (NS_SUCCEEDED(rv)) { @@ -295,7 +294,7 @@ NS_IMETHODIMP nsImapService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr mailnewsUrl = do_QueryInterface(imapUrl); PRBool useLocalCache = PR_FALSE; - folder->HasMsgOffline(atoi(msgKey), &useLocalCache); + folder->HasMsgOffline(atoi(msgKey.get()), &useLocalCache); mailnewsUrl->SetMsgIsInLocalCache(useLocalCache); nsCOMPtr url = do_QueryInterface(imapUrl); @@ -303,9 +302,9 @@ NS_IMETHODIMP nsImapService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL urlSpec.Append("fetch>UID>"); urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(folder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(msgKey); rv = url->SetSpec(urlSpec); @@ -359,8 +358,8 @@ NS_IMETHODIMP nsImapService::OpenAttachment(const char *aContentType, } nsCOMPtr folder; - nsXPIDLCString msgKey; - nsXPIDLCString uriMimePart; + nsCAutoString msgKey; + nsCAutoString uriMimePart; nsCAutoString folderURI; nsMsgKey key; @@ -381,14 +380,14 @@ NS_IMETHODIMP nsImapService::OpenAttachment(const char *aContentType, urlSpec.Append("/fetch>UID>"); urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(folder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(msgKey.get()); urlSpec.Append(uriMimePart.get()); - if (uriMimePart) + if (!uriMimePart.IsEmpty()) { nsCOMPtr mailUrl (do_QueryInterface(imapUrl)); if (mailUrl) @@ -397,7 +396,7 @@ NS_IMETHODIMP nsImapService::OpenAttachment(const char *aContentType, mailUrl->SetFileName(nsDependentCString(aFileName)); } rv = FetchMimePart(imapUrl, nsIImapUrl::nsImapOpenMimePart, folder, imapMessageSink, - nsnull, aDisplayConsumer, msgKey, uriMimePart); + nsnull, aDisplayConsumer, msgKey.get(), uriMimePart.get()); } } // if we got a message sink } // if we parsed the message uri @@ -409,8 +408,8 @@ NS_IMETHODIMP nsImapService::FetchMimePart(nsIURI *aURI, const char *aMessageURI { nsresult rv = NS_OK; nsCOMPtr folder; - nsXPIDLCString msgKey; - nsXPIDLCString mimePart; + nsCAutoString msgKey; + nsCAutoString mimePart; nsCAutoString folderURI; nsMsgKey key; @@ -427,10 +426,10 @@ NS_IMETHODIMP nsImapService::FetchMimePart(nsIURI *aURI, const char *aMessageURI msgurl->SetMsgWindow(aMsgWindow); msgurl->RegisterListener(aUrlListener); - if (mimePart) + if (!mimePart.IsEmpty()) { return FetchMimePart(imapUrl, nsIImapUrl::nsImapMsgFetch, folder, imapMessageSink, - aURL, aDisplayConsumer, msgKey, mimePart); + aURL, aDisplayConsumer, msgKey.get(), mimePart.get()); } } } @@ -446,8 +445,8 @@ NS_IMETHODIMP nsImapService::DisplayMessage(const char* aMessageURI, { nsresult rv = NS_OK; nsCOMPtr folder; - nsXPIDLCString msgKey; - nsXPIDLCString mimePart; + nsCAutoString msgKey; + nsCAutoString mimePart; nsCAutoString folderURI; nsMsgKey key; nsCAutoString messageURI(aMessageURI); @@ -496,10 +495,10 @@ NS_IMETHODIMP nsImapService::DisplayMessage(const char* aMessageURI, rv = CreateStartOfImapUrl(aMessageURI, getter_AddRefs(imapUrl), folder, aUrlListener, urlSpec, hierarchySeparator); if (NS_FAILED(rv)) return rv; - if (mimePart) + if (!mimePart.IsEmpty()) { return FetchMimePart(imapUrl, nsIImapUrl::nsImapMsgFetch, folder, imapMessageSink, - aURL, aDisplayConsumer, msgKey, mimePart); + aURL, aDisplayConsumer, msgKey.get(), mimePart.get()); } nsCOMPtr msgurl (do_QueryInterface(imapUrl)); @@ -514,7 +513,7 @@ NS_IMETHODIMP nsImapService::DisplayMessage(const char* aMessageURI, nsCOMPtr aMsgIncomingServer; if (imapMessageSink) - imapMessageSink->GetMessageSizeFromDB(msgKey, PR_TRUE, &messageSize); + imapMessageSink->GetMessageSizeFromDB(msgKey.get(), PR_TRUE, &messageSize); msgurl->SetMsgWindow(aMsgWindow); @@ -577,7 +576,7 @@ NS_IMETHODIMP nsImapService::DisplayMessage(const char* aMessageURI, prefBranch->GetBoolPref("mailnews.mark_message_read.delay", &forcePeek); rv = FetchMessage(imapUrl, forcePeek ? nsIImapUrl::nsImapMsgFetchPeek : nsIImapUrl::nsImapMsgFetch, folder, imapMessageSink, - aMsgWindow, aDisplayConsumer, msgKey, PR_FALSE, (mPrintingOperation) ? "print" : nsnull, aURL); + aMsgWindow, aDisplayConsumer, msgKey.get(), PR_FALSE, (mPrintingOperation) ? "print" : nsnull, aURL); } } return rv; @@ -627,9 +626,6 @@ nsresult nsImapService::FetchMimePart(nsIImapUrl * aImapUrl, if (mPrintingOperation) urlSpec.Append("?header=print"); - // mscott - this cast to a char * is okay...there's a bug in the XPIDL - // compiler that is preventing in string parameters from showing up as - // const char *. hopefully they will fix it soon. rv = url->SetSpec(urlSpec); rv = aImapUrl->SetImapAction(actionToUse /* nsIImapUrl::nsImapMsgFetch */); @@ -727,7 +723,7 @@ nsImapService::CopyMessage(const char * aSrcMailboxURI, nsIStreamListener * if (NS_FAILED(rv)) return rv; nsCOMPtr folder; - nsXPIDLCString msgKey; + nsCAutoString msgKey; rv = DecomposeImapURI(aSrcMailboxURI, getter_AddRefs(folder), getter_Copies(msgKey)); if (NS_SUCCEEDED(rv)) { @@ -738,7 +734,7 @@ nsImapService::CopyMessage(const char * aSrcMailboxURI, nsIStreamListener * nsCAutoString urlSpec; PRUnichar hierarchySeparator = GetHierarchyDelimiter(folder); PRBool hasMsgOffline = PR_FALSE; - nsMsgKey key = atoi(msgKey); + nsMsgKey key = atoi(msgKey.get()); rv = CreateStartOfImapUrl(aSrcMailboxURI, getter_AddRefs(imapUrl), folder, aUrlListener, urlSpec, hierarchySeparator); @@ -753,7 +749,7 @@ nsImapService::CopyMessage(const char * aSrcMailboxURI, nsIStreamListener * nsImapAction imapAction = nsIImapUrl::nsImapOnlineToOfflineCopy; if (moveMessage) imapAction = nsIImapUrl::nsImapOnlineToOfflineMove; - rv = FetchMessage(imapUrl,imapAction, folder, imapMessageSink,aMsgWindow, streamSupport, msgKey, PR_FALSE, nsnull, aURL); + rv = FetchMessage(imapUrl,imapAction, folder, imapMessageSink,aMsgWindow, streamSupport, msgKey.get(), PR_FALSE, nsnull, aURL); } // if we got an imap message sink } // if we decomposed the imap message return rv; @@ -771,7 +767,7 @@ nsImapService::CopyMessages(nsMsgKeyArray *keys, nsIMsgFolder *srcFolder, nsIStr if (!streamSupport || NS_FAILED(rv)) return rv; nsCOMPtr folder = srcFolder; - nsXPIDLCString msgKey; + nsCAutoString msgKey; if (NS_SUCCEEDED(rv)) { nsCOMPtr imapMessageSink(do_QueryInterface(folder, &rv)); @@ -780,7 +776,7 @@ nsImapService::CopyMessages(nsMsgKeyArray *keys, nsIMsgFolder *srcFolder, nsIStr // we generate the uri for the first message so that way on down the line, // GetMessage in nsCopyMessageStreamListener will get an unescaped username // and be able to find the msg hdr. See bug 259656 for details - nsXPIDLCString uri; + nsCString uri; srcFolder->GenerateMessageURI(keys->GetAt(0), getter_Copies(uri)); nsCString messageIds; @@ -789,12 +785,9 @@ nsImapService::CopyMessages(nsMsgKeyArray *keys, nsIMsgFolder *srcFolder, nsIStr nsCOMPtr imapUrl; nsCAutoString urlSpec; PRUnichar hierarchySeparator = GetHierarchyDelimiter(folder); - rv = CreateStartOfImapUrl(uri, getter_AddRefs(imapUrl), folder, aUrlListener, urlSpec, hierarchySeparator); + rv = CreateStartOfImapUrl(uri.get(), getter_AddRefs(imapUrl), folder.get(), aUrlListener, urlSpec, hierarchySeparator); nsImapAction action; - if (moveMessage) - action = nsIImapUrl::nsImapOnlineToOfflineMove; - else - action = nsIImapUrl::nsImapOnlineToOfflineCopy; + action = (moveMessage) ? nsIImapUrl::nsImapOnlineToOfflineMove : nsIImapUrl::nsImapOnlineToOfflineCopy; imapUrl->SetCopyState(aMailboxCopy); // now try to display the message rv = FetchMessage(imapUrl, action, folder, imapMessageSink, @@ -828,7 +821,7 @@ NS_IMETHODIMP nsImapService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgW if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aMsgFolder, getter_Copies(folderName)); nsCOMPtr mailNewsUrl = do_QueryInterface(imapUrl); @@ -837,7 +830,7 @@ NS_IMETHODIMP nsImapService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgW urlSpec.Append("/search>UID>"); urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append('>'); // escape aSearchUri so that IMAP special characters (i.e. '\') // won't be replaced with '/' in NECKO. @@ -908,7 +901,7 @@ NS_IMETHODIMP nsImapService::SaveMessageToDisk(const char *aMessageURI, nsresult rv = NS_OK; nsCOMPtr folder; nsCOMPtr imapUrl; - nsXPIDLCString msgKey; + nsCAutoString msgKey; rv = DecomposeImapURI(aMessageURI, getter_AddRefs(folder), getter_Copies(msgKey)); if (NS_FAILED(rv)) return rv; @@ -916,7 +909,7 @@ NS_IMETHODIMP nsImapService::SaveMessageToDisk(const char *aMessageURI, PRBool hasMsgOffline = PR_FALSE; if (folder) - folder->HasMsgOffline(atoi(msgKey), &hasMsgOffline); + folder->HasMsgOffline(atoi(msgKey.get()), &hasMsgOffline); nsCAutoString urlSpec; PRUnichar hierarchySeparator = GetHierarchyDelimiter(folder); @@ -938,7 +931,7 @@ NS_IMETHODIMP nsImapService::SaveMessageToDisk(const char *aMessageURI, nsCOMPtr saveAsListener; mailnewsUrl->GetSaveAsListener(aAddDummyEnvelope, aFile, getter_AddRefs(saveAsListener)); - return FetchMessage(imapUrl, nsIImapUrl::nsImapSaveMessageToDisk, folder, imapMessageSink, aMsgWindow, saveAsListener, msgKey, PR_FALSE, nsnull, aURL); + return FetchMessage(imapUrl, nsIImapUrl::nsImapSaveMessageToDisk, folder, imapMessageSink, aMsgWindow, saveAsListener, msgKey.get(), PR_FALSE, nsnull, aURL); } return rv; @@ -1003,9 +996,9 @@ nsImapService::FetchMessage(nsIImapUrl * aImapUrl, urlSpec.Append("fetch>UID>"); urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(messageIdentifierList); @@ -1101,8 +1094,8 @@ nsImapService::StreamMessage(const char *aMessageURI, nsISupports *aConsumer, nsIURI **aURL) { nsCOMPtr folder; - nsXPIDLCString msgKey; - nsXPIDLCString mimePart; + nsCAutoString msgKey; + nsCAutoString mimePart; nsCAutoString folderURI; nsMsgKey key; @@ -1147,7 +1140,7 @@ nsImapService::StreamMessage(const char *aMessageURI, nsISupports *aConsumer, msgurl->SetMsgIsInLocalCache(PR_TRUE); rv = FetchMessage(imapUrl, nsIImapUrl::nsImapMsgFetchPeek, folder, imapMessageSink, - aMsgWindow, aConsumer, msgKey, aConvertData, aAdditionalHeader, aURL); + aMsgWindow, aConsumer, msgKey.get(), aConvertData, aAdditionalHeader, aURL); } } return rv; @@ -1162,8 +1155,8 @@ nsImapService::CreateStartOfImapUrl(const char * aImapURI, nsIImapUrl ** imapUrl { nsresult rv = NS_OK; char *hostname = nsnull; - nsXPIDLCString username; - nsXPIDLCString escapedUsername; + nsCAutoString username; + nsCAutoString escapedUsername; rv = aImapMailFolder->GetHostname(&hostname); if (NS_FAILED(rv)) return rv; @@ -1174,8 +1167,8 @@ nsImapService::CreateStartOfImapUrl(const char * aImapURI, nsIImapUrl ** imapUrl return rv; } - if (((const char*)username) && username[0]) - *((char **)getter_Copies(escapedUsername)) = nsEscape(username, url_XAlphas); + if (!username.IsEmpty()) + *((char **)getter_Copies(escapedUsername)) = nsEscape(username.get(), url_XAlphas); PRInt32 port = IMAP_PORT; nsCOMPtr server; @@ -1199,7 +1192,7 @@ nsImapService::CreateStartOfImapUrl(const char * aImapURI, nsIImapUrl ** imapUrl msgurl->SetUri(aImapURI); urlSpec = "imap://"; - urlSpec.Append((const char *) escapedUsername); + urlSpec.Append(escapedUsername); urlSpec.Append('@'); urlSpec.Append(hostname); urlSpec.Append(':'); @@ -1208,9 +1201,6 @@ nsImapService::CreateStartOfImapUrl(const char * aImapURI, nsIImapUrl ** imapUrl // *** jefft - force to parse the urlSpec in order to search for // the correct incoming server - // mscott - this cast to a char * is okay...there's a bug in the XPIDL - // compiler that is preventing in string parameters from showing up as - // const char *. hopefully they will fix it soon. rv = mailnewsUrl->SetSpec(urlSpec); hierarchyDelimiter = kOnlineHierarchySeparatorUnknown; @@ -1263,10 +1253,10 @@ nsImapService::GetHeaders(nsIEventTarget * aClientEventTarget, urlSpec.Append(">"); urlSpec.Append(char (hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(messageIdentifierList); rv = uri->SetSpec(urlSpec); @@ -1321,10 +1311,10 @@ nsImapService::GetBodyStart(nsIEventTarget * aClientEventTarget, urlSpec.Append(">"); urlSpec.Append(char (hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(messageIdentifierList); urlSpec.Append(">"); @@ -1369,10 +1359,10 @@ nsresult nsImapService::FolderCommand(nsIEventTarget * clientEventTarget, urlSpec.Append(command); urlSpec.Append(char (hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(imapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) rv = GetImapConnectionAndLoadUrl(clientEventTarget, imapUrl, @@ -1450,9 +1440,9 @@ nsImapService::Biff(nsIEventTarget * aClientEventTarget, urlSpec.Append("/Biff>"); urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.AppendInt(uidHighWater); rv = uri->SetSpec(urlSpec); @@ -1526,10 +1516,10 @@ nsImapService::DeleteMessages(nsIEventTarget * aClientEventTarget, urlSpec.Append(">"); urlSpec.Append(char (hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(messageIdentifierList); rv = uri->SetSpec(urlSpec); @@ -1632,9 +1622,9 @@ nsresult nsImapService::DiddleFlags(nsIEventTarget * aClientEventTarget, urlSpec.Append(messageIdsAreUID ? uidString : sequenceString); urlSpec.Append(">"); urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aImapMailFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(messageIdentifierList); urlSpec.Append('>'); @@ -1769,60 +1759,57 @@ NS_IMETHODIMP nsImapService::DiscoverChildren(nsIEventTarget* aClientEventTarget, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, - const char *folderPath, + const char *folderPath, nsIURI** aURL) { - NS_ASSERTION (aImapMailFolder && aClientEventTarget, - "Oops ... null aClientEventTarget or aImapMailFolder"); - if (!aImapMailFolder || ! aClientEventTarget) - return NS_ERROR_NULL_POINTER; - - nsCOMPtr aImapUrl; - nsCAutoString urlSpec; + NS_ASSERTION (aImapMailFolder && aClientEventTarget, + "Oops ... null aClientEventTarget or aImapMailFolder"); + if (!aImapMailFolder || ! aClientEventTarget) + return NS_ERROR_NULL_POINTER; - PRUnichar hierarchySeparator = GetHierarchyDelimiter(aImapMailFolder); - nsresult rv = CreateStartOfImapUrl(nsnull, getter_AddRefs(aImapUrl), - aImapMailFolder, - aUrlListener, urlSpec, hierarchySeparator); - if (NS_SUCCEEDED (rv)) + nsCOMPtr aImapUrl; + nsCAutoString urlSpec; + + PRUnichar hierarchySeparator = GetHierarchyDelimiter(aImapMailFolder); + nsresult rv = CreateStartOfImapUrl(nsnull, getter_AddRefs(aImapUrl), + aImapMailFolder, + aUrlListener, urlSpec, hierarchySeparator); + if (NS_SUCCEEDED (rv)) + { + rv = SetImapUrlSink(aImapMailFolder, aImapUrl); + + if (NS_SUCCEEDED(rv)) { - rv = SetImapUrlSink(aImapMailFolder, aImapUrl); + if (folderPath && *folderPath) + { + nsCOMPtr uri = do_QueryInterface(aImapUrl); - if (NS_SUCCEEDED(rv)) - { - if (folderPath && *folderPath) - { - nsCOMPtr uri = do_QueryInterface(aImapUrl); - - urlSpec.Append("/discoverchildren>"); - urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append(folderPath); - // mscott - this cast to a char * is okay...there's a bug in the XPIDL - // compiler that is preventing in string parameters from showing up as - // const char *. hopefully they will fix it soon. - rv = uri->SetSpec(urlSpec); + urlSpec.Append("/discoverchildren>"); + urlSpec.Append(char(hierarchySeparator)); + urlSpec.Append(folderPath); + rv = uri->SetSpec(urlSpec); // Make sure the uri has the same hierarchy separator as the one in msg folder // obj if it's not kOnlineHierarchySeparatorUnknown (ie, '^'). char uriDelimiter; nsresult rv1 = aImapUrl->GetOnlineSubDirSeparator(&uriDelimiter); if (NS_SUCCEEDED (rv1) && hierarchySeparator != kOnlineHierarchySeparatorUnknown && - uriDelimiter != hierarchySeparator) + uriDelimiter != hierarchySeparator) aImapUrl->SetOnlineSubDirSeparator((char)hierarchySeparator); - if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventTarget, - aImapUrl, - nsnull, aURL); - } - else - { - rv = NS_ERROR_NULL_POINTER; - } - } + if (NS_SUCCEEDED(rv)) + rv = GetImapConnectionAndLoadUrl(aClientEventTarget, + aImapUrl, + nsnull, aURL); + } + else + { + rv = NS_ERROR_NULL_POINTER; + } } - return rv; + } + return rv; } @@ -1893,16 +1880,16 @@ nsImapService::OnlineMessageCopy(nsIEventTarget* aClientEventTarget, urlSpec.Append('>'); urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aSrcFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append('>'); urlSpec.Append(messageIds); urlSpec.Append('>'); urlSpec.Append(char(hierarchySeparator)); folderName.Adopt(strdup("")); GetFolderName(aDstFolder, getter_Copies(folderName)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) @@ -1934,11 +1921,11 @@ nsresult nsImapService::OfflineAppendFromFile(nsIFile* aFile, rv = destDB->GetOfflineOpForKey(fakeKey, PR_TRUE, getter_AddRefs(op)); if (NS_SUCCEEDED(rv) && op) { - nsXPIDLCString destFolderUri; + nsCString destFolderUri; aDstFolder->GetURI(getter_Copies(destFolderUri)); op->SetOperation(nsIMsgOfflineImapOperation::kAppendDraft); // ### do we care if it's a template? - op->SetDestinationFolderURI(destFolderUri); + op->SetDestinationFolderURI(destFolderUri.get()); nsCOMPtr offlineStore; rv = aDstFolder->GetOfflineStoreOutputStream(getter_AddRefs(offlineStore)); @@ -2070,7 +2057,7 @@ nsImapService::AppendMessageFromFile(nsIEventTarget* aClientEventTarget, urlSpec.Append(char(hierarchySeparator)); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(aDstFolder, getter_Copies(folderName)); urlSpec.Append(folderName); @@ -2162,20 +2149,19 @@ nsImapService::MoveFolder(nsIEventTarget* eventTarget, nsIMsgFolder* srcFolder, if (mailNewsUrl) mailNewsUrl->SetMsgWindow(msgWindow); char hierarchySeparator = kOnlineHierarchySeparatorUnknown; - nsXPIDLCString folderName; + nsCString folderName; nsCOMPtr uri = do_QueryInterface(imapUrl); GetFolderName(srcFolder, getter_Copies(folderName)); urlSpec.Append("/movefolderhierarchy>"); urlSpec.Append(hierarchySeparator); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append('>'); - folderName.Adopt(strdup("")); GetFolderName(dstFolder, getter_Copies(folderName)); - if ( folderName && folderName[0]) + if (!folderName.IsEmpty()) { urlSpec.Append(hierarchySeparator); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); } rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) @@ -2215,16 +2201,16 @@ nsImapService::RenameLeaf(nsIEventTarget* eventTarget, nsIMsgFolder* srcFolder, nsCOMPtr mailNewsUrl = do_QueryInterface(imapUrl); if (mailNewsUrl) mailNewsUrl->SetMsgWindow(msgWindow); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(srcFolder, getter_Copies(folderName)); urlSpec.Append("/rename>"); urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append('>'); urlSpec.Append(char(hierarchySeparator)); - nsCAutoString cStrFolderName(NS_STATIC_CAST(const char *, folderName)); + nsCAutoString cStrFolderName(folderName); // Unescape the name before looking for parent path nsUnescape(cStrFolderName.BeginWriting()); PRInt32 leafNameStart = @@ -2239,11 +2225,11 @@ nsImapService::RenameLeaf(nsIEventTarget* eventTarget, nsIMsgFolder* srcFolder, CopyUTF16toMUTF7(nsDependentString(newLeafName), utfNewName); char* escapedNewName = nsEscape(utfNewName.get(), url_Path); if (!escapedNewName) return NS_ERROR_OUT_OF_MEMORY; - nsXPIDLCString escapedSlashName; + nsCString escapedSlashName; rv = nsImapUrl::EscapeSlashes(escapedNewName, getter_Copies(escapedSlashName)); NS_ENSURE_SUCCESS(rv, rv); nsCRT::free(escapedNewName); - urlSpec.Append(escapedSlashName.get()); + urlSpec.Append(escapedSlashName); rv = uri->SetSpec(urlSpec); if (NS_SUCCEEDED(rv)) @@ -2279,16 +2265,16 @@ nsImapService::CreateFolder(nsIEventTarget* eventTarget, nsIMsgFolder* parent, { nsCOMPtr uri = do_QueryInterface(imapUrl); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(parent, getter_Copies(folderName)); urlSpec.Append("/create>"); urlSpec.Append(char(hierarchySeparator)); if (!folderName.IsEmpty()) { - nsXPIDLCString canonicalName; + nsCString canonicalName; - nsImapUrl::ConvertToCanonicalFormat(folderName, (char) hierarchySeparator, getter_Copies(canonicalName)); - urlSpec.Append((const char *) canonicalName); + nsImapUrl::ConvertToCanonicalFormat(folderName.get(), (char) hierarchySeparator, getter_Copies(canonicalName)); + urlSpec.Append(canonicalName); urlSpec.Append(char(hierarchySeparator)); } @@ -2332,13 +2318,13 @@ nsImapService::EnsureFolderExists(nsIEventTarget* eventTarget, nsIMsgFolder* par { nsCOMPtr uri = do_QueryInterface(imapUrl); - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(parent, getter_Copies(folderName)); urlSpec.Append("/ensureExists>"); urlSpec.Append(char(hierarchySeparator)); if (!folderName.IsEmpty()) { - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(char(hierarchySeparator)); } nsCAutoString utfNewName; @@ -2431,7 +2417,7 @@ nsresult nsImapService::GetServerFromUrl(nsIImapUrl *aImapUrl, nsIMsgIncomingSer nsCOMPtr mailnewsUrl = do_QueryInterface(aImapUrl); nsresult rv; - nsXPIDLCString folderName; + nsCString folderName; // if we can't get a folder name out of the url then I think this is an error aImapUrl->CreateCanonicalSourceFolderPathString(getter_Copies(folderName)); @@ -2501,7 +2487,7 @@ NS_IMETHODIMP nsImapService::NewURI(const nsACString &aSpec, mailnewsUrl->SetSpec(aSpec); } - nsXPIDLCString folderName; + nsCString folderName; // if we can't get a folder name out of the url then I think this is an error aImapUrl->CreateCanonicalSourceFolderPathString(getter_Copies(folderName)); @@ -2530,7 +2516,7 @@ NS_IMETHODIMP nsImapService::NewURI(const nsACString &aSpec, nsCOMPtr subFolder; if (imapRoot) { - imapRoot->FindOnlineSubFolder(folderName, getter_AddRefs(subFolder)); + imapRoot->FindOnlineSubFolder(folderName.get(), getter_AddRefs(subFolder)); folder = do_QueryInterface(subFolder, &rv); } if (NS_SUCCEEDED(rv)) @@ -2540,14 +2526,14 @@ NS_IMETHODIMP nsImapService::NewURI(const nsACString &aSpec, nsCOMPtr msgFolder = do_QueryInterface(folder); rv = SetImapUrlSink(msgFolder, aImapUrl); - nsXPIDLCString msgKey; + nsCAutoString msgKey; - nsXPIDLCString messageIdString; + nsCString messageIdString; aImapUrl->CreateListOfMessageIdsString(getter_Copies(messageIdString)); - if (messageIdString.get()) + if (!messageIdString.IsEmpty()) { PRBool useLocalCache = PR_FALSE; - msgFolder->HasMsgOffline(atoi(messageIdString), &useLocalCache); + msgFolder->HasMsgOffline(atoi(messageIdString.get()), &useLocalCache); mailnewsUrl->SetMsgIsInLocalCache(useLocalCache); } } @@ -2602,7 +2588,7 @@ NS_IMETHODIMP nsImapService::NewChannel(nsIURI *aURI, nsIChannel **_retval) nsCOMPtr server; rv = GetServerFromUrl(imapUrl, getter_AddRefs(server)); NS_ENSURE_SUCCESS(rv, rv); - nsXPIDLCString folderName; + nsCString folderName; imapUrl->CreateCanonicalSourceFolderPathString(getter_Copies(folderName)); if (folderName.IsEmpty()) { @@ -2620,7 +2606,7 @@ NS_IMETHODIMP nsImapService::NewChannel(nsIURI *aURI, nsIChannel **_retval) nsCOMPtr subFolder; if (imapRoot) { - imapRoot->FindOnlineSubFolder(folderName, getter_AddRefs(subFolder)); + imapRoot->FindOnlineSubFolder(folderName.get(), getter_AddRefs(subFolder)); aFolder = do_QueryInterface(subFolder); } nsCOMPtr parent; @@ -2656,7 +2642,7 @@ NS_IMETHODIMP nsImapService::NewChannel(nsIURI *aURI, nsIChannel **_retval) NS_ENSURE_SUCCESS(rv, rv); wwatch->GetNewPrompter(nsnull, getter_AddRefs(dialog)); - nsXPIDLString statusString, confirmText; + nsString statusString, confirmText; nsCOMPtr bundle; rv = IMAPGetStringBundle(getter_AddRefs(bundle)); NS_ENSURE_SUCCESS(rv, rv); @@ -2672,7 +2658,7 @@ NS_IMETHODIMP nsImapService::NewChannel(nsIURI *aURI, nsIChannel **_retval) NS_ENSURE_SUCCESS(rv,rv); PRBool confirmResult = PR_FALSE; - rv = dialog->Confirm(nsnull, confirmText, &confirmResult); + rv = dialog->Confirm(nsnull, confirmText.get(), &confirmResult); NS_ENSURE_SUCCESS(rv, rv); if (confirmResult) @@ -2732,9 +2718,9 @@ NS_IMETHODIMP nsImapService::NewChannel(nsIURI *aURI, nsIChannel **_retval) rv = mailSession->GetTopmostMsgWindow(getter_AddRefs(msgWindow)); if (NS_SUCCEEDED(rv) && msgWindow) { - nsXPIDLCString uri; + nsCString uri; rootFolder->GetURI(getter_Copies(uri)); - uri.Append('/'); + uri.Append('/'); uri.Append(fullFolderName); nsCOMPtr windowCommands; msgWindow->GetWindowCommands(getter_AddRefs(windowCommands)); @@ -3058,7 +3044,7 @@ nsImapService::IssueCommandOnMsgs(nsIEventTarget *aClientEventTarget, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(anImapFolder, getter_Copies(folderName)); urlSpec.Append("/"); urlSpec.Append(aCommand); @@ -3066,7 +3052,7 @@ nsImapService::IssueCommandOnMsgs(nsIEventTarget *aClientEventTarget, urlSpec.Append(uidString); urlSpec.Append(">"); urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(uids); rv = mailNewsUrl->SetSpec(urlSpec); @@ -3111,11 +3097,11 @@ nsImapService::FetchCustomMsgAttribute(nsIEventTarget *aClientEventTarget, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(anImapFolder, getter_Copies(folderName)); urlSpec.Append("/customFetch>UID>"); urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(uids); urlSpec.Append(">"); @@ -3162,11 +3148,11 @@ nsImapService::StoreCustomKeywords(nsIEventTarget *aClientEventTarget, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; + nsCString folderName; GetFolderName(anImapFolder, getter_Copies(folderName)); urlSpec.Append("/customKeywords>UID>"); urlSpec.Append(char(hierarchySeparator)); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); urlSpec.Append(">"); urlSpec.Append(uids); urlSpec.Append(">"); diff --git a/mailnews/imap/src/nsImapUndoTxn.cpp b/mailnews/imap/src/nsImapUndoTxn.cpp index e2871090c8f..ae7f21e8cc3 100644 --- a/mailnews/imap/src/nsImapUndoTxn.cpp +++ b/mailnews/imap/src/nsImapUndoTxn.cpp @@ -40,7 +40,6 @@ #include "nsMsgImapCID.h" #include "nsIMsgHdr.h" #include "nsImapUndoTxn.h" -#include "nsXPIDLString.h" #include "nsIIMAPHostSessionList.h" #include "nsIMsgIncomingServer.h" #include "nsIDBFolderInfo.h" @@ -69,7 +68,7 @@ nsImapMoveCopyMsgTxn::Init( m_urlListener = do_QueryInterface(urlListener, &rv); m_srcKeyArray.CopyArray(srcKeyArray); m_dupKeyArray.CopyArray(srcKeyArray); - nsXPIDLCString uri; + nsCString uri; rv = srcFolder->GetURI(getter_Copies(uri)); nsCString protocolType(uri); protocolType.SetLength(protocolType.FindChar(':')); @@ -574,18 +573,18 @@ NS_IMETHODIMP nsImapOfflineTxn::RedoTransaction(void) nsCOMPtr dstFolder = do_QueryReferent(m_dstFolder, &rv); if (dstFolder) { - nsXPIDLCString folderURI; + nsCString folderURI; dstFolder->GetURI(getter_Copies(folderURI)); if (m_opType == nsIMsgOfflineImapOperation::kMsgMoved) { - op->SetDestinationFolderURI(folderURI); // offline move + op->SetDestinationFolderURI(folderURI.get()); // offline move } if (m_opType == nsIMsgOfflineImapOperation::kMsgCopy) { op->SetOperation(nsIMsgOfflineImapOperation::kMsgMoved); - op->AddMessageCopyOperation(folderURI); // offline copy + op->AddMessageCopyOperation(folderURI.get()); // offline copy } dstFolder->SummaryChanged(); } @@ -606,9 +605,9 @@ NS_IMETHODIMP nsImapOfflineTxn::RedoTransaction(void) rv = destDB->GetOfflineOpForKey(hdrKey, PR_TRUE, getter_AddRefs(op)); if (NS_SUCCEEDED(rv) && op) { - nsXPIDLCString folderURI; + nsCString folderURI; srcFolder->GetURI(getter_Copies(folderURI)); - op->SetSourceFolderURI(folderURI); + op->SetSourceFolderURI(folderURI.get()); } dstFolder->SummaryChanged(); destDB->Close(PR_TRUE); diff --git a/mailnews/imap/src/nsImapUrl.cpp b/mailnews/imap/src/nsImapUrl.cpp index 3a310e959e3..7e0e486c91b 100644 --- a/mailnews/imap/src/nsImapUrl.cpp +++ b/mailnews/imap/src/nsImapUrl.cpp @@ -52,7 +52,6 @@ #include "nsIImapIncomingServer.h" #include "nsMsgBaseCID.h" #include "nsImapUtils.h" -#include "nsXPIDLString.h" #include "nsReadableUtils.h" #include "nsAutoLock.h" #include "nsIMAPNamespace.h" @@ -975,10 +974,10 @@ NS_IMETHODIMP nsImapUrl::AllocateServerPath(const char * canonicalPath, char onl char *canonicalPath; if (onlineDelimiter != '/') { - nsXPIDLCString escapedPath; + nsCString escapedPath; EscapeSlashes(folderName, getter_Copies(escapedPath)); - canonicalPath = ReplaceCharsInCopiedString(escapedPath, onlineDelimiter , '/'); + canonicalPath = ReplaceCharsInCopiedString(escapedPath.get(), onlineDelimiter , '/'); } else { @@ -1283,7 +1282,7 @@ NS_IMETHODIMP nsImapUrl::GetUri(char** aURI) { *aURI = nsnull; PRUint32 key = m_listOfMessageIds ? atoi(m_listOfMessageIds) : 0; - nsXPIDLCString canonicalPath; + nsCString canonicalPath; AllocateCanonicalPath(m_sourceCanonicalFolderPathSubString, m_onlineSubDirSeparator, (getter_Copies(canonicalPath))); nsCString fullFolderPath("/"); fullFolderPath.Append(m_userName); @@ -1294,14 +1293,12 @@ NS_IMETHODIMP nsImapUrl::GetUri(char** aURI) fullFolderPath.Append('/'); fullFolderPath.Append(canonicalPath); - char * baseMessageURI; - nsCreateImapBaseMessageURI(fullFolderPath.get(), &baseMessageURI); + nsCString baseMessageURI; + nsCreateImapBaseMessageURI(fullFolderPath.get(), baseMessageURI); nsCAutoString uriStr; - rv = nsBuildImapMessageURI(baseMessageURI, key, uriStr); - nsCRT::free(baseMessageURI); + rv = nsBuildImapMessageURI(baseMessageURI.get(), key, uriStr); *aURI = ToNewCString(uriStr); } - return rv; } @@ -1527,12 +1524,12 @@ nsresult nsImapUrl::GetMsgFolder(nsIMsgFolder **msgFolder) // if we have a RDF URI, then try to get the folder for that URI and then ask the folder // for it's charset.... - nsXPIDLCString uri; + nsCString uri; GetUri(getter_Copies(uri)); - NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(!uri.IsEmpty(), NS_ERROR_FAILURE); nsCOMPtr msg; - GetMsgDBHdrFromURI(uri, getter_AddRefs(msg)); + GetMsgDBHdrFromURI(uri.get(), getter_AddRefs(msg)); NS_ENSURE_TRUE(msg, NS_ERROR_FAILURE); nsresult rv = msg->GetFolder(msgFolder); NS_ENSURE_SUCCESS(rv,rv); @@ -1591,7 +1588,7 @@ NS_IMETHODIMP nsImapUrl::SetShouldStoreMsgOffline(PRBool aShouldStoreMsgOffline) NS_IMETHODIMP nsImapUrl::GetMessageHeader(nsIMsgDBHdr ** aMsgHdr) { - nsXPIDLCString uri; + nsCString uri; nsresult rv = GetUri(getter_Copies(uri)); NS_ENSURE_SUCCESS(rv, rv); return GetMsgDBHdrFromURI(uri.get(), aMsgHdr); diff --git a/mailnews/imap/src/nsImapUrl.h b/mailnews/imap/src/nsImapUrl.h index 735a275855d..361f7429f97 100644 --- a/mailnews/imap/src/nsImapUrl.h +++ b/mailnews/imap/src/nsImapUrl.h @@ -48,7 +48,6 @@ #include "nsIImapMessageSink.h" #include "nsWeakPtr.h" -#include "nsXPIDLString.h" #include "nsIFile.h" class nsImapUrl : public nsIImapUrl, public nsMsgMailNewsUrl, public nsIMsgMessageUrl, public nsIMsgI18NUrl diff --git a/mailnews/imap/src/nsImapUtils.cpp b/mailnews/imap/src/nsImapUtils.cpp index 93d63ab5695..67459e04a7f 100644 --- a/mailnews/imap/src/nsImapUtils.cpp +++ b/mailnews/imap/src/nsImapUtils.cpp @@ -219,23 +219,16 @@ nsresult nsBuildImapMessageURI(const char *baseURI, PRUint32 key, nsCString& uri return NS_OK; } -nsresult nsCreateImapBaseMessageURI(const char *baseURI, char **baseMessageURI) +nsresult nsCreateImapBaseMessageURI(const char *baseURI, nsCString &baseMessageURI) { - if(!baseMessageURI) - return NS_ERROR_NULL_POINTER; - nsCAutoString tailURI(baseURI); - // chop off mailbox:/ + // chop off imap:/ if (tailURI.Find(kImapRootURI) == 0) tailURI.Cut(0, PL_strlen(kImapRootURI)); - nsCAutoString baseURIStr(kImapMessageRootURI); - baseURIStr += tailURI; - - *baseMessageURI = ToNewCString(baseURIStr); - if(!*baseMessageURI) - return NS_ERROR_OUT_OF_MEMORY; + baseMessageURI = kImapMessageRootURI; + baseMessageURI += tailURI; return NS_OK; } diff --git a/mailnews/imap/src/nsImapUtils.h b/mailnews/imap/src/nsImapUtils.h index 49d9d8c6aa0..b6a325746e7 100644 --- a/mailnews/imap/src/nsImapUtils.h +++ b/mailnews/imap/src/nsImapUtils.h @@ -62,7 +62,7 @@ extern nsresult nsBuildImapMessageURI(const char *baseURI, PRUint32 key, nsCString& uri); extern nsresult -nsCreateImapBaseMessageURI(const char *baseURI, char **baseMessageURI); +nsCreateImapBaseMessageURI(const char *baseURI, nsCString &baseMessageURI); void AllocateImapUidString(PRUint32 *msgUids, PRUint32 &msgCount, nsImapFlagAndUidState *flagState, nsCString &returnString); void ParseUidString(const char *uidString, nsMsgKeyArray &keys); diff --git a/mailnews/local/src/nsLocalMailFolder.cpp b/mailnews/local/src/nsLocalMailFolder.cpp index 4ea3c42366e..030eb5619e2 100644 --- a/mailnews/local/src/nsLocalMailFolder.cpp +++ b/mailnews/local/src/nsLocalMailFolder.cpp @@ -3161,7 +3161,7 @@ NS_IMETHODIMP nsMsgLocalMailFolder::SelectDownloadMsg() if (mDownloadState == DOWNLOAD_STATE_GOTMSG && mDownloadWindow) { nsCAutoString newuri; - nsBuildLocalMessageURI(mBaseMessageURI, mDownloadSelectKey, newuri); + nsBuildLocalMessageURI(mBaseMessageURI.get(), mDownloadSelectKey, newuri); nsCOMPtr windowCommands; mDownloadWindow->GetWindowCommands(getter_AddRefs(windowCommands)); if (windowCommands) @@ -3291,7 +3291,7 @@ nsMsgLocalMailFolder::GetIncomingServerType() nsresult nsMsgLocalMailFolder::CreateBaseMessageURI(const char *aURI) { - return nsCreateLocalBaseMessageURI(aURI, &mBaseMessageURI); + return nsCreateLocalBaseMessageURI(aURI, mBaseMessageURI); } NS_IMETHODIMP @@ -3308,7 +3308,7 @@ nsMsgLocalMailFolder::OnStartRunningUrl(nsIURI * aUrl) nsCOMPtr popsink; rv = popurl->GetPop3Sink(getter_AddRefs(popsink)); if (NS_SUCCEEDED(rv)) - popsink->SetBaseMessageUri(mBaseMessageURI); + popsink->SetBaseMessageUri(mBaseMessageURI.get()); } } return nsMsgDBFolder::OnStartRunningUrl(aUrl); diff --git a/mailnews/local/src/nsLocalUtils.cpp b/mailnews/local/src/nsLocalUtils.cpp index 557b4ef876b..5fd0e93c08d 100644 --- a/mailnews/local/src/nsLocalUtils.cpp +++ b/mailnews/local/src/nsLocalUtils.cpp @@ -259,23 +259,16 @@ nsresult nsBuildLocalMessageURI(const char *baseURI, PRUint32 key, nsCString& ur return NS_OK; } -nsresult nsCreateLocalBaseMessageURI(const char *baseURI, char **baseMessageURI) +nsresult nsCreateLocalBaseMessageURI(const char *baseURI, nsCString &baseMessageURI) { - if(!baseMessageURI) - return NS_ERROR_NULL_POINTER; - nsCAutoString tailURI(baseURI); // chop off mailbox:/ if (tailURI.Find(kMailboxRootURI) == 0) tailURI.Cut(0, PL_strlen(kMailboxRootURI)); - nsCAutoString baseURIStr(kMailboxMessageRootURI); - baseURIStr += tailURI; - - *baseMessageURI = ToNewCString(baseURIStr); - if(!*baseMessageURI) - return NS_ERROR_OUT_OF_MEMORY; + baseMessageURI = kMailboxMessageRootURI; + baseMessageURI += tailURI; return NS_OK; } diff --git a/mailnews/local/src/nsLocalUtils.h b/mailnews/local/src/nsLocalUtils.h index a52c3004336..81213625399 100644 --- a/mailnews/local/src/nsLocalUtils.h +++ b/mailnews/local/src/nsLocalUtils.h @@ -54,7 +54,7 @@ nsresult nsBuildLocalMessageURI(const char* baseURI, PRUint32 key, nsCString& uri); nsresult -nsCreateLocalBaseMessageURI(const char *baseURI, char **baseMessageURI); +nsCreateLocalBaseMessageURI(const char *baseURI, nsCString &baseMessageURI); void nsEscapeNativePath(nsCString& nativePath); diff --git a/mailnews/local/src/nsMailboxUrl.cpp b/mailnews/local/src/nsMailboxUrl.cpp index 9dc3034e2bf..2a2ca415901 100644 --- a/mailnews/local/src/nsMailboxUrl.cpp +++ b/mailnews/local/src/nsMailboxUrl.cpp @@ -199,12 +199,11 @@ NS_IMETHODIMP nsMailboxUrl::GetUri(char ** aURI) (void) MsgMailboxGetURI(m_file, baseUri); if (baseUri.IsEmpty()) m_baseURL->GetSpec(baseUri); - char * baseMessageURI; - nsCreateLocalBaseMessageURI(baseUri.get(), &baseMessageURI); + nsCString baseMessageURI; + nsCreateLocalBaseMessageURI(baseUri.get(), baseMessageURI); char * uri = nsnull; nsCAutoString uriStr; - nsBuildLocalMessageURI(baseMessageURI, m_messageKey, uriStr); - nsCRT::free(baseMessageURI); + nsBuildLocalMessageURI(baseMessageURI.get(), m_messageKey, uriStr); uri = ToNewCString(uriStr); *aURI = uri; } diff --git a/mailnews/news/src/nsNewsFolder.cpp b/mailnews/news/src/nsNewsFolder.cpp index 3c308eedf67..d5049788efb 100644 --- a/mailnews/news/src/nsNewsFolder.cpp +++ b/mailnews/news/src/nsNewsFolder.cpp @@ -1450,7 +1450,7 @@ nsresult nsMsgNewsFolder::CreateBaseMessageURI(const char *aURI) { nsresult rv; - rv = nsCreateNewsBaseMessageURI(aURI, &mBaseMessageURI); + rv = nsCreateNewsBaseMessageURI(aURI, mBaseMessageURI); return rv; } diff --git a/mailnews/news/src/nsNewsUtils.cpp b/mailnews/news/src/nsNewsUtils.cpp index 1cb49363098..047aee236ab 100644 --- a/mailnews/news/src/nsNewsUtils.cpp +++ b/mailnews/news/src/nsNewsUtils.cpp @@ -73,23 +73,16 @@ nsParseNewsMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key) return NS_ERROR_FAILURE; } -nsresult nsCreateNewsBaseMessageURI(const char *baseURI, char **baseMessageURI) +nsresult nsCreateNewsBaseMessageURI(const char *baseURI, nsCString &baseMessageURI) { - if(!baseMessageURI) - return NS_ERROR_NULL_POINTER; + nsCAutoString tailURI(baseURI); - nsCAutoString tailURI(baseURI); + // chop off news:/ + if (tailURI.Find(kNewsRootURI) == 0) + tailURI.Cut(0, PL_strlen(kNewsRootURI)); - // chop off mailbox:/ - if (tailURI.Find(kNewsRootURI) == 0) - tailURI.Cut(0, PL_strlen(kNewsRootURI)); - - nsCAutoString baseURIStr(kNewsMessageRootURI); - baseURIStr += tailURI; + baseMessageURI = kNewsMessageRootURI; + baseMessageURI += tailURI; - *baseMessageURI = ToNewCString(baseURIStr); - if(!*baseMessageURI) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; + return NS_OK; } diff --git a/mailnews/news/src/nsNewsUtils.h b/mailnews/news/src/nsNewsUtils.h index a62d581357c..3ffc909c072 100644 --- a/mailnews/news/src/nsNewsUtils.h +++ b/mailnews/news/src/nsNewsUtils.h @@ -54,7 +54,7 @@ extern nsresult nsParseNewsMessageURI(const char* uri, nsCString& messageUriWithoutKey, PRUint32 *key); extern nsresult -nsCreateNewsBaseMessageURI(const char *baseURI, char **baseMessageURI); +nsCreateNewsBaseMessageURI(const char *baseURI, nsCString &baseMessageURI); #endif //NS_NEWSUTILS_H