diff --git a/mailnews/mime/cthandlers/vcard/mimevcrd.cpp b/mailnews/mime/cthandlers/vcard/mimevcrd.cpp new file mode 100644 index 00000000000..72c0c17222f --- /dev/null +++ b/mailnews/mime/cthandlers/vcard/mimevcrd.cpp @@ -0,0 +1,1773 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "mimevcrd.h" +#include "xpgetstr.h" +#include "xp_core.h" +#include "xp_mem.h" +#include "vcc.h" +#include "vobject.h" +#include "libi18n.h" +#include "mimecth.h" +#include "mimexpcom.h" + +#include "prmem.h" +#include "plstr.h" + +static int MimeInlineTextVCard_parse_line (char *, PRInt32, MimeObject *); +static int MimeInlineTextVCard_parse_eof (MimeObject *, PRBool); +static int MimeInlineTextVCard_parse_begin (MimeObject *obj); + +static int unique = 0; + +extern int MK_OUT_OF_MEMORY; + +extern "C" int MK_LDAP_COMMON_NAME; +extern "C" int MK_LDAP_FAX_NUMBER; +extern "C" int MK_LDAP_GIVEN_NAME; +extern "C" int MK_LDAP_LOCALITY; +extern "C" int MK_LDAP_PHOTOGRAPH; +extern "C" int MK_LDAP_EMAIL_ADDRESS; +extern "C" int MK_LDAP_MANAGER; +extern "C" int MK_LDAP_ORGANIZATION; +extern "C" int MK_LDAP_OBJECT_CLASS; +extern "C" int MK_LDAP_ORG_UNIT; +extern "C" int MK_LDAP_POSTAL_ADDRESS; +extern "C" int MK_LDAP_SECRETARY; +extern "C" int MK_LDAP_SURNAME; +extern "C" int MK_LDAP_STREET; +extern "C" int MK_LDAP_PHONE_NUMBER; +extern "C" int MK_LDAP_CAR_LICENSE; +extern "C" int MK_LDAP_BUSINESS_CAT; +extern "C" int MK_LDAP_DEPT_NUMBER; +extern "C" int MK_LDAP_DESCRIPTION; +extern "C" int MK_LDAP_EMPLOYEE_TYPE; +extern "C" int MK_LDAP_POSTAL_CODE; +extern "C" int MK_LDAP_TITLE; +extern "C" int MK_LDAP_REGION; +extern "C" int MK_LDAP_DOM_TYPE; +extern "C" int MK_LDAP_INTL_TYPE; +extern "C" int MK_LDAP_POSTAL_TYPE; +extern "C" int MK_LDAP_PARCEL_TYPE; +extern "C" int MK_LDAP_WORK_TYPE; +extern "C" int MK_LDAP_HOME_TYPE; +extern "C" int MK_LDAP_PREF_TYPE; +extern "C" int MK_LDAP_VOICE_TYPE; +extern "C" int MK_LDAP_FAX_TYPE; +extern "C" int MK_LDAP_MSG_TYPE; +extern "C" int MK_LDAP_CELL_TYPE; +extern "C" int MK_LDAP_PAGER_TYPE; +extern "C" int MK_LDAP_BBS_TYPE; +extern "C" int MK_LDAP_MODEM_TYPE; +extern "C" int MK_LDAP_CAR_TYPE; +extern "C" int MK_LDAP_ISDN_TYPE; +extern "C" int MK_LDAP_VIDEO_TYPE; +extern "C" int MK_LDAP_AOL_TYPE; +extern "C" int MK_LDAP_APPLELINK_TYPE; +extern "C" int MK_LDAP_ATTMAIL_TYPE; +extern "C" int MK_LDAP_CSI_TYPE; +extern "C" int MK_LDAP_EWORLD_TYPE; +extern "C" int MK_LDAP_INTERNET_TYPE; +extern "C" int MK_LDAP_IBMMAIL_TYPE; +extern "C" int MK_LDAP_MCIMAIL_TYPE; +extern "C" int MK_LDAP_POWERSHARE_TYPE; +extern "C" int MK_LDAP_PRODIGY_TYPE; +extern "C" int MK_LDAP_TLX_TYPE; +extern "C" int MK_LDAP_MIDDLE_NAME; +extern "C" int MK_LDAP_NAME_PREFIX; +extern "C" int MK_LDAP_NAME_SUFFIX; +extern "C" int MK_LDAP_TZ; +extern "C" int MK_LDAP_GEO; +extern "C" int MK_LDAP_SOUND; +extern "C" int MK_LDAP_REVISION; +extern "C" int MK_LDAP_VERSION; +extern "C" int MK_LDAP_KEY; +extern "C" int MK_LDAP_LOGO; +extern "C" int MK_LDAP_X400; +extern "C" int MK_LDAP_BIRTHDAY; +extern "C" int MK_LDAP_ADDRESS; +extern "C" int MK_LDAP_LABEL; +extern "C" int MK_LDAP_MAILER; +extern "C" int MK_LDAP_ROLE; +extern "C" int MK_LDAP_UPDATEURL; +extern "C" int MK_LDAP_COOLTALKADDRESS; +extern "C" int MK_LDAP_USEHTML; +extern "C" int MK_ADDR_VIEW_COMPLETE_VCARD; +extern "C" int MK_ADDR_VIEW_CONDENSED_VCARD; +extern "C" int MK_MSG_ADD_TO_ADDR_BOOK; +extern "C" int MK_ADDR_DEFAULT_DLS; +extern "C" int MK_ADDR_SPECIFIC_DLS; +extern "C" int MK_ADDR_HOSTNAMEIP; +extern "C" int MK_ADDR_CONFINFO; +extern "C" int MK_ADDR_ADDINFO; + +static int BeginVCard (MimeObject *obj); +static int EndVCard (MimeObject *obj); +static int WriteOutVCard (MimeObject *obj, VObject* v); +static int WriteOutEachVCardProperty (MimeObject *obj, VObject* v, int* numEmail); +static int WriteOutVCardProperties (MimeObject *obj, VObject* v, int* numEmail); +static int WriteLineToStream (MimeObject *obj, const char *line); + +static void GetEmailProperties (VObject* o, char ** attribName); +static void GetTelephoneProperties (VObject* o, char ** attribName); +static void GetAddressProperties (VObject* o, char ** attribName); +static int WriteValue (MimeObject *obj, const char *); +static int WriteAttribute (MimeObject *obj, const char *); +static int WriteOutVCardPhoneProperties (MimeObject *obj, VObject* v); +static int WriteOutEachVCardPhoneProperty (MimeObject *obj, VObject* o); + +typedef struct + { + const char *attributeName; + int resourceId; + } AttributeName; + +#define kNumAttributes 12 + +/* + * These functions are the public interface for this content type + * handler and will be called in by the mime component. + */ +#define VCARD_CONTENT_TYPE "text/x-vcard" + + /* This is the object definition. Note: we will set the superclass + to NULL and manually set this on the class creation */ +MimeDefClass(MimeInlineTextVCard, MimeInlineTextVCardClass, + mimeInlineTextVCardClass, NULL); + +PUBLIC char * +MIME_GetContentType(void) +{ + return VCARD_CONTENT_TYPE; +} + +PUBLIC MimeObjectClass * +MIME_CreateContentTypeHandlerClass(const char *content_type, + contentTypeHandlerInitStruct *initStruct) +{ + MimeObjectClass *clazz = (MimeObjectClass *)&mimeInlineTextVCardClass; + /* + * Must set the superclass by hand. + */ + if (!COM_GetmimeInlineTextClass()) + return NULL; + + clazz->superclass = (MimeObjectClass *)COM_GetmimeInlineTextClass(); + initStruct->force_inline_display = PR_TRUE; + return clazz; +} + +/* + * Implementation of VCard clazz + */ +static int +MimeInlineTextVCardClassInitialize(MimeInlineTextVCardClass *clazz) +{ + MimeObjectClass *oclass = (MimeObjectClass *) clazz; + PR_ASSERT(!oclass->class_initialized); + oclass->parse_begin = MimeInlineTextVCard_parse_begin; + oclass->parse_line = MimeInlineTextVCard_parse_line; + oclass->parse_eof = MimeInlineTextVCard_parse_eof; + +return 0; +} + +static int +MimeInlineTextVCard_parse_begin (MimeObject *obj) +{ +// int status = ((MimeObjectClass*)&mimeLeafClass)->parse_begin(obj); + int status = ((MimeObjectClass*)COM_GetmimeLeafClass())->parse_begin(obj); + MimeInlineTextVCardClass *clazz; + if (status < 0) return status; + + if (!obj->output_p) return 0; + if (!obj->options || !obj->options->write_html_p) return 0; + + /* This is a fine place to write out any HTML before the real meat begins. + In this sample code, we tell it to start a table. */ + + clazz = ((MimeInlineTextVCardClass *) obj->clazz); + /* initialize vcard string to empty; */ + StrAllocCopy(clazz->vCardString, ""); + + return 0; +} + + +static int +MimeInlineTextVCard_parse_line (char *line, PRInt32 length, MimeObject *obj) +{ + /* This routine gets fed each line of data, one at a time. In my + sample, I spew it out as a table row, putting everything + between colons in its own table cell.*/ + + char* linestring; + MimeInlineTextVCardClass *clazz = ((MimeInlineTextVCardClass *) obj->clazz); + + if (!obj->output_p) return 0; + if (!obj->options || !obj->options->output_fn) return 0; + if (!obj->options->write_html_p) { + return COM_MimeObject_write(obj, line, length, PR_TRUE); + } + + linestring = (char *) PR_MALLOC (length + 1); + + if (linestring) { + XP_STRNCPY_SAFE((char *)linestring, line, length + 1); + StrAllocCat (clazz->vCardString, linestring); + PR_Free (linestring); + } + + return 0; +} + + +static int +MimeInlineTextVCard_parse_eof (MimeObject *obj, PRBool abort_p) +{ + int status = 0; + MimeInlineTextVCardClass *clazz = ((MimeInlineTextVCardClass *) obj->clazz); + VObject *t, *v; + + if (obj->closed_p) return 0; + + /* Run parent method first, to flush out any buffered data. */ +// status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p); + status = ((MimeObjectClass*)COM_GetmimeInlineTextClass())->parse_eof(obj, abort_p); + if (status < 0) return status; + + if (!clazz->vCardString) return 0; + + v = Parse_MIME(clazz->vCardString, PL_strlen(clazz->vCardString)); + + if (clazz->vCardString) { + PR_Free ((char*) clazz->vCardString); + clazz->vCardString = NULL; + } + + if (obj->output_p && obj->options && obj->options->write_html_p && + obj->options->headers != MimeHeadersCitation) { + /* This is a fine place to write any closing HTML. In fact, you may + want all the writing to be here, and all of the above would just + collect data into datastructures, though that isn't very + "streaming". */ + t = v; + while (v && status >= 0) { + /* write out html */ + status = WriteOutVCard (obj, v); + /* parse next vcard incase they're embedded */ + v = nextVObjectInList(v); + } + + cleanVObject(t); + } + if (status < 0) return status; + + return 0; +} + +static int WriteEachLineToStream (MimeObject *obj, const char *line) +{ + int status = 0; + char *htmlLine; + int htmlLen = PL_strlen(line) + 1; + + htmlLine = (char *) PR_MALLOC (htmlLen); + if (htmlLine) + { + htmlLine[0] = '\0'; + PL_strcat (htmlLine, line); + status = COM_MimeObject_write(obj, htmlLine, PL_strlen(htmlLine), PR_TRUE); + PR_Free ((void*) htmlLine); + } + else + status = MK_OUT_OF_MEMORY; + + return status; +} + +static int OutputTable (MimeObject *obj, PRBool endTable, PRBool border, char *cellspacing, char *cellpadding, char *bgcolor) +{ + int status = 0; + char * htmlLine = NULL; + + if (endTable) + { + status = WriteEachLineToStream (obj, ""); + } + else + { + int htmlLen = PL_strlen("