gecko-dev/lib/libmsg/msgcflds.cpp

386 lines
8.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "rosetta.h"
#include "msg.h"
#include "errcode.h"
#include "dberror.h"
#include "msgcflds.h"
#include "prefapi.h"
#include "ptrarray.h"
extern "C" {
extern int MK_OUT_OF_MEMORY;
}
MSG_CompositionFields::MSG_CompositionFields()
{
XP_Bool bReturnReceiptOn = FALSE;
PREF_GetBoolPref("mail.request.return_receipt_on", &bReturnReceiptOn);
PREF_GetIntPref("mail.request.return_receipt", &m_receiptType);
SetReturnReceipt (bReturnReceiptOn);
}
MSG_CompositionFields::MSG_CompositionFields(MSG_CompositionFields* c)
{
int i;
for (i=0 ; i<sizeof(m_headers) / sizeof(char*) ; i++) {
if (c->m_headers[i]) {
m_headers[i] = XP_STRDUP(c->m_headers[i]);
}
}
if (c->m_body) {
m_body = XP_STRDUP(c->m_body);
}
for (i=0 ; i<c->m_numforward ; i++) {
AddForwardURL(c->m_forwardurl[i]);
}
for (i=0; i<sizeof(m_boolHeaders)/sizeof(XP_Bool) ; i++) {
m_boolHeaders[i] = c->m_boolHeaders[i];
}
m_receiptType = c->m_receiptType;
}
MSG_CompositionFields::~MSG_CompositionFields()
{
int i;
for (i=0 ; i<sizeof(m_headers) / sizeof(char*) ; i++) {
FREEIF(m_headers[i]);
}
FREEIF(m_body);
for (i=0 ; i<m_numforward ; i++) {
delete [] m_forwardurl[i];
}
delete [] m_forwardurl;
}
int MSG_CompositionFields::SetNewsUrlHeader (const char *hostPort, XP_Bool xxx, const char *group)
{
// Here's where we allow URLs in the newsgroups: header
int status = -1;
if (hostPort && group) // must have a group
{
char *newsPostUrl = PR_smprintf ("%s://%s/", HG71654 "news", hostPort);
if (newsPostUrl)
{
SetHeader (MSG_NEWSPOSTURL_HEADER_MASK, newsPostUrl);
XP_FREE(newsPostUrl);
status = 0; // we succeeded, no need to keep looking at this header
}
else
status = MK_OUT_OF_MEMORY;
}
return status;
}
int MSG_CompositionFields::ParseNewsgroupsForUrls (const char *value)
{
int status = 0;
// Here we pull apart the comma-separated header value and look for news
// URLs. We'll use the URL to set the newspost URL to determine the host
msg_StringArray values (TRUE /*owns memory for strings*/);
values.ImportTokenList (value);
for (int i = 0; i < values.GetSize(); i++)
{
const char *singleValue = values.GetAt(i);
if (NEWS_TYPE_URL == NET_URL_Type (singleValue))
{
char *hostPort, *group, *id, *data;
XP_Bool xxx;
if (0 == NET_parse_news_url (value, &hostPort, &xxx, &group, &id, &data))
{
status = SetNewsUrlHeader (hostPort, xxx, group);
if (status == 0)
{
values.RemoveAt(i); // Remove the URL spec for this group
values.Add (group); // Add in the plain old group name
}
FREEIF (hostPort);
FREEIF (group);
FREEIF (id);
FREEIF (data);
}
}
}
char *newValue = values.ExportTokenList ();
if (newValue)
{
status = SetHeader (MSG_NEWSGROUPS_HEADER_MASK, newValue);
XP_FREE(newValue);
}
return status;
}
int
MSG_CompositionFields::SetHeader(MSG_HEADER_SET header, const char* value)
{
int status = 0;
// Since colon is not a legal character in a newsgroup name under son-of-1036
// we're assuming that such a header contains a URL, and we should parse it out
// to infer the news server.
if (value && MSG_NEWSGROUPS_HEADER_MASK == header && XP_STRCHR(value, ':'))
return ParseNewsgroupsForUrls (value);
int i = DecodeHeader(header);
if (i >= 0)
{
char* old = m_headers[i]; // Done with careful paranoia, in case the
// value given is the old value (or worse,
// a substring of the old value, as does
// happen here and there.)
if (value != old)
{
if (value)
{
m_headers[i] = XP_STRDUP(value);
if (!m_headers[i])
status = MK_OUT_OF_MEMORY;
}
else
m_headers[i] = NULL;
FREEIF(old);
}
}
return status;
}
extern "C"const char* MSG_GetCompFieldsHeader(MSG_CompositionFields *fields,
MSG_HEADER_SET header)
{
return fields->GetHeader(header);
}
const char*
MSG_CompositionFields::GetHeader(MSG_HEADER_SET header)
{
int i = DecodeHeader(header);
if (i >= 0) {
return m_headers[i] ? m_headers[i] : "";
}
return NULL;
}
int
MSG_CompositionFields::SetBoolHeader(MSG_BOOL_HEADER_SET header, XP_Bool bValue)
{
int status = 0;
XP_ASSERT ((int) header >= (int) MSG_RETURN_RECEIPT_BOOL_HEADER_MASK &&
(int) header < (int) MSG_LAST_BOOL_HEADER_MASK);
if ( (int) header < (int) MSG_RETURN_RECEIPT_BOOL_HEADER_MASK ||
(int) header >= (int) MSG_LAST_BOOL_HEADER_MASK )
return -1;
m_boolHeaders[header] = bValue;
return status;
}
XP_Bool
MSG_CompositionFields::GetBoolHeader(MSG_BOOL_HEADER_SET header)
{
XP_ASSERT ((int) header >= (int) MSG_RETURN_RECEIPT_BOOL_HEADER_MASK &&
(int) header < (int) MSG_LAST_BOOL_HEADER_MASK);
if ( (int) header < (int) MSG_RETURN_RECEIPT_BOOL_HEADER_MASK ||
(int) header >= (int) MSG_LAST_BOOL_HEADER_MASK )
return FALSE;
return m_boolHeaders[header];
}
int
MSG_CompositionFields::SetBody(const char* value)
{
FREEIF(m_body);
if (value) {
m_body = XP_STRDUP(value);
if (!m_body) return MK_OUT_OF_MEMORY;
}
return 0;
}
const char*
MSG_CompositionFields::GetBody()
{
return m_body ? m_body : "";
}
int
MSG_CompositionFields::AppendBody(const char* value)
{
if (!value || !*value) return 0;
if (!m_body) {
return SetBody(value);
} else {
char* tmp = (char*) XP_ALLOC(XP_STRLEN(m_body) + XP_STRLEN(value) + 1);
if (tmp) {
XP_STRCPY(tmp, m_body);
XP_STRCAT(tmp, value);
XP_FREE(m_body);
m_body = tmp;
} else {
return MK_OUT_OF_MEMORY;
}
}
return 0;
}
int
MSG_CompositionFields::DecodeHeader(MSG_HEADER_SET header)
{
int result;
switch(header) {
case MSG_FROM_HEADER_MASK:
result = 0;
break;
case MSG_REPLY_TO_HEADER_MASK:
result = 1;
break;
case MSG_TO_HEADER_MASK:
result = 2;
break;
case MSG_CC_HEADER_MASK:
result = 3;
break;
case MSG_BCC_HEADER_MASK:
result = 4;
break;
case MSG_FCC_HEADER_MASK:
result = 5;
break;
case MSG_NEWSGROUPS_HEADER_MASK:
result = 6;
break;
case MSG_FOLLOWUP_TO_HEADER_MASK:
result = 7;
break;
case MSG_SUBJECT_HEADER_MASK:
result = 8;
break;
case MSG_ATTACHMENTS_HEADER_MASK:
result = 9;
break;
case MSG_ORGANIZATION_HEADER_MASK:
result = 10;
break;
case MSG_REFERENCES_HEADER_MASK:
result = 11;
break;
case MSG_OTHERRANDOMHEADERS_HEADER_MASK:
result = 12;
break;
case MSG_NEWSPOSTURL_HEADER_MASK:
result = 13;
break;
case MSG_PRIORITY_HEADER_MASK:
result = 14;
break;
case MSG_NEWS_FCC_HEADER_MASK:
result = 15;
break;
case MSG_MESSAGE_ENCODING_HEADER_MASK:
result = 16;
break;
case MSG_CHARACTER_SET_HEADER_MASK:
result = 17;
break;
case MSG_MESSAGE_ID_HEADER_MASK:
result = 18;
break;
case MSG_NEWS_BCC_HEADER_MASK:
result = 19;
break;
case MSG_HTML_PART_HEADER_MASK:
result = 20;
break;
case MSG_DEFAULTBODY_HEADER_MASK:
result = 21;
break;
case MSG_X_TEMPLATE_HEADER_MASK:
result = 22;
break;
default:
XP_ASSERT(0);
result = -1;
break;
}
XP_ASSERT(result < sizeof(m_headers) / sizeof(char*));
return result;
}
int
MSG_CompositionFields::AddForwardURL(const char* url)
{
XP_ASSERT(url && *url);
if (!url || !*url) return -1;
if (m_numforward >= m_maxforward) {
m_maxforward += 10;
char** tmp = new char* [m_maxforward];
if (!tmp) return MK_OUT_OF_MEMORY;
for (int32 i=0 ; i<m_numforward ; i++) {
tmp[i] = m_forwardurl[i];
}
delete [] m_forwardurl;
m_forwardurl = tmp;
}
m_forwardurl[m_numforward] = new char[XP_STRLEN(url) + 1];
if (!m_forwardurl[m_numforward]) return MK_OUT_OF_MEMORY;
XP_STRCPY(m_forwardurl[m_numforward], url);
m_numforward++;
return 0;
}
int32
MSG_CompositionFields::GetNumForwardURL()
{
return m_numforward;
}
const char*
MSG_CompositionFields::GetForwardURL(int32 which)
{
XP_ASSERT(which >= 0 && which < m_numforward);
if (which >= 0 && which < m_numforward) {
return m_forwardurl[which];
}
return NULL;
}