diff --git a/mailnews/mime/public/nsIMsgHeaderParser.idl b/mailnews/mime/public/nsIMsgHeaderParser.idl index b7d2da3609d..e517940fea3 100644 --- a/mailnews/mime/public/nsIMsgHeaderParser.idl +++ b/mailnews/mime/public/nsIMsgHeaderParser.idl @@ -23,6 +23,8 @@ #include "nsISupports.idl" #include "nsrootidl.idl" +interface nsISimpleEnumerator; + %{C++ // {932C53A5-F398-11d2-82B7-444553540002} #define NS_MSGHEADERPARSER_CID \ @@ -30,11 +32,28 @@ { 0x82, 0xb7, 0x44, 0x45, 0x53, 0x54, 0x0, 0x2 } } %} +// This small nifty little interface helps make nsIMsgHeaderParser +// more useable from an xpconnect point of view. +[scriptable, uuid(8987735B-C239-11d3-98AD-001083010E9B)] +interface nsIMsgHeaderParserResult : nsISupports { + string getAddressAndName(out string address); + readonly attribute unsigned long currentResultNumber; + readonly attribute unsigned long totalNumberOfResults; +}; + /* * nsIMsgRFCParser Interface declaration */ [scriptable, uuid(10A88A11-729E-11d2-804A-006008128C4E)] interface nsIMsgHeaderParser : nsISupports { + // This is a version of ParseHeaderAddresses which is much easier to use + // from xp connect. Basically, you get an enumerator back which you use + // to enumerate over the parsed header objects. QI each object returned by + // the enumerator for nsIMsgHeaderParserResult and you can ask it anything + // you want =). + + nsISimpleEnumerator ParseHeadersWithEnumerator(in string charset, + in string line); /* Given a string which contains a list of Header addresses, parses it into their component names and mailboxes. @@ -49,7 +68,7 @@ interface nsIMsgHeaderParser : nsISupports { Either of the provided pointers may be NULL if the caller is not interested in those components. */ - void ParseHeaderAddresses ([const] in string charset, [const] in string line, out string names, + void ParseHeaderAddresses (in string charset, in string line, out string names, out string addresses, out PRUint32 numAddresses); /* Given a string which contains a list of Header addresses, returns a @@ -59,7 +78,7 @@ interface nsIMsgHeaderParser : nsISupports { Caller must call PL_strfree on returnValue (which is allocated by the function) */ - void ExtractHeaderAddressMailboxes ([const] in string charset, [const] in string line, out string mailboxes); + void ExtractHeaderAddressMailboxes (in string charset, in string line, out string mailboxes); /* Given a string which contains a list of Header addresses, returns a @@ -70,7 +89,7 @@ interface nsIMsgHeaderParser : nsISupports { Caller must PL_strfree usernames. */ - void ExtractHeaderAddressNames ([const] in string charset, [const] in string line, out string userNames); + void ExtractHeaderAddressNames (in string charset, in string line, out string userNames); /* Like MSG_ExtractHeaderAddressNames(), but only returns the first name in the list, if there is more than one. @@ -79,7 +98,7 @@ interface nsIMsgHeaderParser : nsISupports { Caller must call PL_strfree on name */ - void ExtractHeaderAddressName ([const] in string charset, [const] in string line, out string name); + void ExtractHeaderAddressName (in string charset, in string line, out string name); /* Given a string which contains a list of Header addresses, returns a new string with the same data, but inserts missing commas, parses and reformats @@ -89,7 +108,7 @@ interface nsIMsgHeaderParser : nsISupports { Caller must call PL_strfree on reformattedAddress */ - void ReformatHeaderAddresses ([const] in string charset, [const] in string line, + void ReformatHeaderAddresses (in string charset, in string line, out string reformattedAddress); /* Returns a copy of ADDRS which may have had some addresses removed. @@ -109,7 +128,7 @@ interface nsIMsgHeaderParser : nsISupports { Caller must call PL_strfree on newAddress which is the return value. */ - void RemoveDuplicateAddresses ([const] in string charset, [const] in string addrs, [const] in string other_addrs, + void RemoveDuplicateAddresses (in string charset, in string addrs, in string other_addrs, in PRBool removeAliasesToMe, out string newAddress); @@ -119,15 +138,14 @@ interface nsIMsgHeaderParser : nsISupports { The caller may pass nsnull for charset and it will be interpreted as "us-ascii". - Caller must call PL_strfree on fullAddress + Caller must call PL_strfree on fullAddress (this is the out parameter) */ - void MakeFullAddress ([const] in string charset, [const] in string name, [const] in string addr, - out string fullAddress); + string MakeFullAddress (in string charset, in string name, in string addr); /* MSG_ParseHeaderAddresses returns quoted parsable addresses This function removes the quoting if you want to show the names to users. e.g. summary file, address book */ - void UnquotePhraseOrAddr ([const] in string charset, [const] in string line, out string lineout); + void UnquotePhraseOrAddr (in string charset, in string line, out string lineout); }; diff --git a/mailnews/mime/src/nsMsgHeaderParser.cpp b/mailnews/mime/src/nsMsgHeaderParser.cpp index f114d134194..b4757579b91 100644 --- a/mailnews/mime/src/nsMsgHeaderParser.cpp +++ b/mailnews/mime/src/nsMsgHeaderParser.cpp @@ -21,10 +21,126 @@ */ #include "msgCore.h" // precompiled header... -#include "nsMsgHeaderParser.h" +#include "nsMsgHeaderParser.h" +#include "nsISimpleEnumerator.h" #include "comi18n.h" #include "prmem.h" +class nsMsgHeaderParserResult : public nsIMsgHeaderParserResult, public nsISimpleEnumerator +{ +public: + nsMsgHeaderParserResult(); + nsresult Init(char * aNames, char * aAddresses, PRUint32 numAddresses); + virtual ~nsMsgHeaderParserResult(); + + NS_DECL_NSIMSGHEADERPARSERRESULT + NS_DECL_ISUPPORTS + NS_DECL_NSISIMPLEENUMERATOR + +protected: + PRUint32 mNumTotalAddresses; + PRUint32 mCurrentPositionInList; + + // list of names and addresses. each name / address is separated by a null byte + // per the description in nsIMsgHeaderParser::ParseHeader + char * mStartofNames; + char * mStartofAddresses; + + // char * ptrs into the null separated strings + char * mCurrentName; + char * mCurrentAddress; + + PRBool mFirstPass; +}; + +NS_IMPL_ISUPPORTS2(nsMsgHeaderParserResult, nsIMsgHeaderParserResult, nsISimpleEnumerator); + +nsMsgHeaderParserResult::nsMsgHeaderParserResult() +{ + NS_INIT_ISUPPORTS(); + mNumTotalAddresses = 0; + mCurrentPositionInList = 0; + mStartofNames = nsnull; + mStartofAddresses = nsnull; + mCurrentName = nsnull; + mCurrentAddress = nsnull; + mFirstPass = PR_TRUE; +} + +nsMsgHeaderParserResult::~nsMsgHeaderParserResult() +{ + // the header parser is not up to date and still uses PL_strdup for the strings it gives us + // so we need to use PR_FREE... + PR_FREEIF(mStartofNames); + PR_FREEIF(mStartofAddresses); +} + +nsresult nsMsgHeaderParserResult::Init(char * aNames, char * aAddresses, PRUint32 numAddresses) +{ + nsresult rv = NS_OK; + mNumTotalAddresses = numAddresses; + mStartofNames = aNames; // we take ownership + mCurrentName = mStartofNames; + mStartofAddresses = aAddresses; + mCurrentAddress = mStartofAddresses; + + return rv; +} + +NS_IMETHODIMP nsMsgHeaderParserResult::GetAddressAndName(char **address, char **name) +{ + nsresult rv = NS_OK; + if (address) + *address = nsCRT::strdup(mCurrentAddress); + if (name) + *name = nsCRT::strdup(mCurrentName); + + return rv; +} + +NS_IMETHODIMP nsMsgHeaderParserResult::GetCurrentResultNumber(PRUint32 *aCurrentResultNumber) +{ + *aCurrentResultNumber = mCurrentPositionInList; + return NS_OK; +} + +NS_IMETHODIMP nsMsgHeaderParserResult::GetTotalNumberOfResults(PRUint32 *aTotalNumberOfResults) +{ + *aTotalNumberOfResults = mNumTotalAddresses; + return NS_OK; +} + +// simple enumerator supports +NS_IMETHODIMP nsMsgHeaderParserResult::HasMoreElements(PRBool * aHasMoreElements) +{ + if (mCurrentPositionInList < mNumTotalAddresses) + *aHasMoreElements = PR_TRUE; + else + *aHasMoreElements = PR_FALSE; + + return NS_OK; +} + +NS_IMETHODIMP nsMsgHeaderParserResult::GetNext(nsISupports ** aNextResultPair) +{ + nsresult rv = NS_OK; + if (aNextResultPair) + { + rv = QueryInterface(NS_GET_IID(nsISupports), (void **) aNextResultPair); + } + // don't increment the ptrs the first time through... + if (!mFirstPass) + { + mCurrentName += nsCRT::strlen(mCurrentName) + 1; + mCurrentAddress += nsCRT::strlen(mCurrentAddress) + 1; + } + else + mFirstPass = PR_FALSE; + + mCurrentPositionInList++; + + return rv; +} /* * Macros used throughout the RFC-822 parsing code. @@ -102,6 +218,31 @@ MimeCharsetConverterClass *nsMsgHeaderParser::GetUSAsciiToUtf8CharsetConverter() return m_USAsciiToUtf8CharsetConverter; } +NS_IMETHODIMP nsMsgHeaderParser::ParseHeadersWithEnumerator(const char *charset, const char *line, + nsISimpleEnumerator **aResultEnumerator) +{ + char * names = nsnull; + char * addresses = nsnull; + PRUint32 numAddresses = 0; + nsresult rv = NS_OK; + + rv = ParseHeaderAddresses(charset, line, &names, &addresses, &numAddresses); + if (NS_SUCCEEDED(rv)) + { + // now shove the results into an enumerator.......i know i should be using the component manager for this...=( + nsMsgHeaderParserResult * parserResult = new nsMsgHeaderParserResult(); + if (parserResult) + { + rv = parserResult->Init(names, addresses, numAddresses); // ownership of all strings is now passed here... + parserResult->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **) aResultEnumerator); + } + else + rv = NS_ERROR_OUT_OF_MEMORY; + } + + return rv; +} + nsresult nsMsgHeaderParser::ParseHeaderAddresses (const char *charset, const char *line, char **names, char **addresses, PRUint32 *numAddresses) { char *utf8Str, *outStrings; diff --git a/mailnews/mime/src/nsMsgHeaderParser.h b/mailnews/mime/src/nsMsgHeaderParser.h index e2705e10118..7aabe18dc0a 100644 --- a/mailnews/mime/src/nsMsgHeaderParser.h +++ b/mailnews/mime/src/nsMsgHeaderParser.h @@ -37,94 +37,20 @@ * RFC-822 parser */ - class nsMsgHeaderParser: public nsIMsgHeaderParser - { - public: - nsMsgHeaderParser(); - virtual ~nsMsgHeaderParser(); +class nsMsgHeaderParser: public nsIMsgHeaderParser +{ +public: + nsMsgHeaderParser(); + virtual ~nsMsgHeaderParser(); - /* this macro defines QueryInterface, AddRef and Release for this class */ - NS_DECL_ISUPPORTS + /* this macro defines QueryInterface, AddRef and Release for this class */ + NS_DECL_ISUPPORTS - /* Given a string which contains a list of Header addresses, parses it into - their component names and mailboxes. - - The returned value is the number of addresses, or a negative error code; - the names and addresses are returned into the provided pointers as - consecutive null-terminated strings. It is up to the caller to free them. - Note that some of the strings may be zero-length. - - Either of the provided pointers may be NULL if the caller is not interested - in those components. - */ - NS_IMETHOD ParseHeaderAddresses (const char *charset, const char *line, char **names, char **addresses, PRUint32 *numAddresses); - - /* Given a string which contains a list of Header addresses, returns a - comma-seperated list of just the `mailbox' portions. - - Caller must call PL_Free on mailboxes string returned by these calls. - */ - NS_IMETHOD ExtractHeaderAddressMailboxes (const char *charset, const char *line, char ** mailboxes); - - - /* Given a string which contains a list of Header addresses, returns a - comma-seperated list of just the `user name' portions. If any of - the addresses doesn't have a name, then the mailbox is used instead. - - Caller must call PL_Free on userNames - */ - NS_IMETHOD ExtractHeaderAddressNames (const char *charset, const char *line, char ** userNames); - - /* Like MSG_ExtractHeaderAddressNames(), but only returns the first name - in the list, if there is more than one. - - Caller must call PL_Free on the returned firstName string. - */ - NS_IMETHOD ExtractHeaderAddressName (const char *charset, const char *line, char ** firstName); - - /* Given a string which contains a list of Header addresses, returns a new - string with the same data, but inserts missing commas, parses and reformats - it, and wraps long lines with newline-tab. - - Caller must call PL_Free on the returned string - */ - NS_IMETHOD ReformatHeaderAddresses (const char *charset, const char *line, char ** reformattedAddress); - - /* Returns a copy of ADDRS which may have had some addresses removed. - Addresses are removed if they are already in either ADDRS or OTHER_ADDRS. - (If OTHER_ADDRS contain addresses which are not in ADDRS, they are not - added. That argument is for passing in addresses that were already - mentioned in other header fields.) - - Addresses are considered to be the same if they contain the same mailbox - part (case-insensitive.) Real names and other comments are not compared. - - removeAliasesToMe allows the address parser to use the preference which - contains regular expressions which also mean 'me' for the purpose of - stripping the user's email address(es) out of addrs - - Caller must call PL_Free on outString. - */ - NS_IMETHOD RemoveDuplicateAddresses (const char *charset, const char *addrs, const char *other_addrs, PRBool removeAliasesToMe, char ** outString); - - - /* Given an e-mail address and a person's name, cons them together into a - single string of the form "name
", doing all the necessary quoting. - A new string is returned, which you must free when you're done with it. - - Caller must call PL_Free on fullAddress - */ - NS_IMETHOD MakeFullAddress (const char *charset, const char* name, const char* addr, char ** fullAddress); - - /* MSG_ParseHeaderAddresses returns quoted parsable addresses - This function removes the quoting if you want to show the - names to users. e.g. summary file, address book - */ - NS_IMETHOD UnquotePhraseOrAddr (const char *charset, const char *line, char** lineout); + NS_DECL_NSIMSGHEADERPARSER MimeCharsetConverterClass *GetUSAsciiToUtf8CharsetConverter(); - protected: - MimeCharsetConverterClass *m_USAsciiToUtf8CharsetConverter; - }; +protected: + MimeCharsetConverterClass *m_USAsciiToUtf8CharsetConverter; +}; #endif /* nsMSGRFCPARSER_h__ */