|
导入不标准邮件,对邮件标题按GB2312进行处理并编码,尽量保证不出现乱码
mailnews/local/src/nsParseMailbox.cpp
/mailnews/local/src/nsParseMailbox.h- int nsParseMailMessageState::InternSubject (struct message_header *header)
- {
- char *key;
- uint32_t L;
- if (!header || header->length == 0)
- {
- m_newMsgHdr->SetSubject("");
- return 0;
- }
- NS_ASSERTION (header->length == (short) strlen(header->value), "subject corrupt while parsing message");
- key = (char *) header->value; /* #### const evilness */
- L = header->length;
- uint32_t flags;
- (void)m_newMsgHdr->GetFlags(&flags);
- /* strip "Re: " */
- /**
- We trust the X-Mozilla-Status line to be the smartest in almost
- all things. One exception, however, is the HAS_RE flag. Since
- we just parsed the subject header anyway, we expect that parsing
- to be smartest. (After all, what if someone just went in and
- edited the subject line by hand?)
- */
- nsCString modifiedSubject;
- if (NS_MsgStripRE((const char **) &key, &L, getter_Copies(modifiedSubject)))
- flags |= nsMsgMessageFlags::HasRe;
- else
- flags &= ~nsMsgMessageFlags::HasRe;
- m_newMsgHdr->SetFlags(flags); // this *does not* update the mozilla-status header in the local folder
- // if (!*key) return 0; /* To catch a subject of "Re:" */
- // Condense the subject text into as few MIME-2 encoded words as possible.
- #ifdef WE_CONDENSE_MIME_STRINGS
- char *condensedKey = msg_condense_mime2_string(modifiedSubject.IsEmpty() ? key : modifiedSubject.get());
- #else
- char *condensedKey = nullptr;
- #endif
-
- // 如果导入的邮件标题不符合标准格式没有编码,自己按GB2312处理并编码
- bool bStandard = IsStandardFormat(key, header->length);
- if (!bStandard)// 按gb2312处理
- {
- char *pszFixStr= FixStandardFormat(key, header->length);
- if (pszFixStr == nullptr)
- {
- m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
- (modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
- }
- else
- {
- m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
- (modifiedSubject.IsEmpty() ? pszFixStr : modifiedSubject.get()));
- PR_FREEIF(pszFixStr);
- }
- }
- else // 正常处理
- {
- m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
- (modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
- }
- PR_FREEIF(condensedKey);
- return 0;
- }
- bool nsParseMailMessageState::IsStandardFormat(char *pszValue, uint32_t uiLen)
- {
- for (uint32_t i = 0; i < uiLen; i++)
- {
- if (pszValue[i] < 0x20 || pszValue[i] > 0x7e)
- {
- if (pszValue[i] == 0x0d || pszValue[i] == 0x0a)
- continue;
- return false;
- }
- }
- return true;
- }
- char* nsParseMailMessageState::FixStandardFormat(char *pszValue, uint32_t uiLen)
- {
- nsCString UTF8Str;
- nsString UTF16Str;
- const char *pInternal = nullptr;
- ConvertToUnicode("gb2312", pszValue, UTF16Str);
- UTF8Str = NS_ConvertUTF16toUTF8(UTF16Str);
- uint32_t iLen = UTF8Str.GetData(&pInternal);
- char *pBase64 = PL_Base64Encode(pInternal, iLen, nullptr);
- if (pBase64 == nullptr)
- return nullptr;
- char *pszBuffer = (char *)PR_Malloc(PL_strlen(pBase64) + 12 + 10);
- if (pszBuffer == nullptr)
- {
- PR_Free(pBase64);
- return nullptr;
- }
- memset(pszBuffer, 0, PL_strlen(pBase64) + 12 + 10);
- PL_strcat(pszBuffer, "=?UTF-8?B?");
- PL_strcat(pszBuffer, pBase64);
- PL_strcat(pszBuffer, "?=");
- return pszBuffer;
- }
- class nsParseMailMessageState : public nsIMsgParseMailMsgState, public nsIDBChangeListener
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIMSGPARSEMAILMSGSTATE
- NS_DECL_NSIDBCHANGELISTENER
- nsParseMailMessageState();
- virtual ~nsParseMailMessageState();
- void Init(uint32_t fileposition);
- virtual int32_t ParseFolderLine(const char *line, uint32_t lineLength);
- virtual int StartNewEnvelope(const char *line, uint32_t lineLength);
- int ParseHeaders();
- int FinalizeHeaders();
- int ParseEnvelope (const char *line, uint32_t line_size);
- int InternSubject (struct message_header *header);
- static bool IsEnvelopeLine(const char *buf, int32_t buf_size);
- static int msg_UnHex(char C);
- nsCOMPtr<nsIMsgHeaderParser> m_HeaderAddressParser;
- nsCOMPtr<nsIMsgDBHdr> m_newMsgHdr; /* current message header we're building */
- nsCOMPtr<nsIMsgDatabase> m_mailDB;
- nsCOMPtr<nsIMsgDatabase> m_backupMailDB;
- nsMailboxParseState m_state;
- int64_t m_position;
- uint64_t m_envelope_pos;
- uint64_t m_headerstartpos;
- nsByteArray m_headers;
- nsByteArray m_envelope;
- struct message_header m_message_id;
- struct message_header m_references;
- struct message_header m_date;
- struct message_header m_delivery_date;
- struct message_header m_from;
- struct message_header m_sender;
- struct message_header m_newsgroups;
- struct message_header m_subject;
- struct message_header m_status;
- struct message_header m_mozstatus;
- struct message_header m_mozstatus2;
- struct message_header m_in_reply_to;
- struct message_header m_replyTo;
- struct message_header m_content_type;
- struct message_header m_bccList;
- // Support for having multiple To or Cc header lines in a message
- nsVoidArray m_toList;
- nsVoidArray m_ccList;
- struct message_header *GetNextHeaderInAggregate (nsVoidArray &list);
- void GetAggregateHeader (nsVoidArray &list, struct message_header *);
- void ClearAggregateHeader (nsVoidArray &list);
- struct message_header m_envelope_from;
- struct message_header m_envelope_date;
- struct message_header m_priority;
- struct message_header m_account_key;
- struct message_header m_keywords;
- // Mdn support
- struct message_header m_mdn_original_recipient;
- struct message_header m_return_path;
- struct message_header m_mdn_dnt; /* MDN Disposition-Notification-To: header */
- PRTime m_receivedTime;
- uint16_t m_body_lines;
- bool m_IgnoreXMozillaStatus;
- // this enables extensions to add the values of particular headers to
- // the .msf file as properties of nsIMsgHdr. It is initialized from a
- // pref, mailnews.customDBHeaders
- nsTArray<nsCString> m_customDBHeaders;
- struct message_header *m_customDBHeaderValues;
- bool IsStandardFormat(char *pszValue, uint32_t uiLen);
- char *FixStandardFormat(char *pszValue, uint32_t uiLen);
- protected:
- };
- // this should go in some utility class.
- inline int nsParseMailMessageState::msg_UnHex(char C)
- {
- return ((C >= '0' && C <= '9') ? C - '0' :
- ((C >= 'A' && C <= 'F') ? C - 'A' + 10 :
- ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)));
- }
复制代码 |
|