[evolution-mapi] Moved MIME parsing code from camel-mapi-transport to camel-mapi-utils.



commit 8d455ad70bb9191ca307083885ab2d0f64180430
Author: Johnny Jacob <jjohnny novell com>
Date:   Mon Aug 10 09:00:56 2009 +0530

    Moved MIME parsing code from camel-mapi-transport to camel-mapi-utils.

 src/camel/Makefile.am            |    2 +
 src/camel/camel-mapi-transport.c |  360 ++--------------------------------
 src/camel/camel-mapi-utils.c     |  404 ++++++++++++++++++++++++++++++++++++++
 src/camel/camel-mapi-utils.h     |   40 ++++
 4 files changed, 461 insertions(+), 345 deletions(-)
---
diff --git a/src/camel/Makefile.am b/src/camel/Makefile.am
index 3527a33..b2f710c 100644
--- a/src/camel/Makefile.am
+++ b/src/camel/Makefile.am
@@ -18,6 +18,7 @@ libcamelmapi_la_SOURCES = 			\
         camel-mapi-store.c	                \
 	camel-mapi-store-summary.c         	\
 	camel-mapi-summary.c	         	\
+	camel-mapi-utils.c			\
 	camel-mapi-transport.c			
 
 noinst_HEADERS =         			\
@@ -26,6 +27,7 @@ noinst_HEADERS =         			\
 	camel-mapi-store-summary.h         	\
 	camel-mapi-summary.h	         	\
 	camel-mapi-transport.h			\
+	camel-mapi-utils.h			\
 	camel-mapi-private.h			\
 	camel-private.h				
 
diff --git a/src/camel/camel-mapi-transport.c b/src/camel/camel-mapi-transport.c
index 4904dd7..1bef7de 100644
--- a/src/camel/camel-mapi-transport.c
+++ b/src/camel/camel-mapi-transport.c
@@ -62,6 +62,7 @@
 #include "camel-mapi-store.h"
 #include "camel-mapi-folder.h"
 #include "camel-mapi-store-summary.h"
+#include "camel-mapi-utils.h"
 #include <camel/camel-session.h>
 #include <camel/camel-store-summary.h>
 #define d(x) x
@@ -75,265 +76,40 @@ CamelStore *get_store(void);
 
 void	set_store(CamelStore *);
 
-static void
-mapi_item_add_recipient (const char *recipients, OlMailRecipientType type, GSList **recipient_list);
-static mapi_id_t
-mapi_message_item_send (MapiItem *item, GSList *attachments, GSList *recipients);
-
-#if 0
-static void
-mapi_item_debug_dump (MapiItem *item)
-{
-	printf("-----------------\n\n");
-        printf("%s:%s: \n", G_STRLOC, G_STRFUNC);
-	printf("item->header.from : %s\n",item->header.from);
-	//Use Recipient List
-	printf("item->header.subject : %s\n",item->header.subject);
-	//printf("item->msg.body_stream : %s\n",item->msg.body_stream);
-	printf("-----------------\n\n");
-}
-#endif
-
-static void
-mapi_item_set_from(MapiItem *item, const char *from)
-{
-	if (item->header.from) { 
-		free(item->header.from);
-	}
-	item->header.from = strdup(from);
-}
-
-static void
-mapi_item_set_subject(MapiItem *item, const char *subject)
-{
-	if (item->header.subject)
-		free(item->header.subject);
-
-	item->header.subject = g_strdup(subject);
-}
-
-#define MAX_READ_SIZE 0x1000
-
-static void
-mapi_item_set_body_stream (MapiItem *item, CamelStream *body, MapiItemPartType part_type)
-{
-	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
-	guint32	read_size = 0;
-	ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
-
-	camel_seekable_stream_seek((CamelSeekableStream *)body, 0, CAMEL_STREAM_SET);
-
-	stream->value = g_byte_array_new ();
-
-	while((read_size = camel_stream_read(body, (char *)buf, STREAM_SIZE))){
-		if (read_size == -1) 
-			return;
-
-		stream->value = g_byte_array_append (stream->value, buf, read_size);
-	}
-
-	switch (part_type) {
-	case PART_TYPE_TEXT_HTML :
-		stream->proptag = PR_HTML;
-		break;
-	case PART_TYPE_PLAIN_TEXT:
-		stream->proptag = PR_BODY_UNICODE;
-		break;
-	}
-
-	if (stream->value->len < MAX_READ_SIZE)
-		item->msg.body_parts = g_slist_append (item->msg.body_parts, stream);
-	else
-		item->generic_streams = g_slist_append (item->generic_streams, stream);
 
-}
-
-static gboolean
-mapi_item_add_attach (MapiItem *item, CamelMimePart *part, CamelStream *content_stream)
+/*CreateItem would return the MID of the new message or '0' if we fail.*/
+static mapi_id_t
+mapi_message_item_send (MapiItem *item)
 {
-	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
-	const gchar *content_id = NULL;
-	guint32	read_size, flag, i = 0;
-
-	ExchangeMAPIAttachment *item_attach;
-	ExchangeMAPIStream *stream; 
-
-	const gchar *filename = camel_mime_part_get_filename (part);
-	
-	item_attach = g_new0 (ExchangeMAPIAttachment, 1);
-
-	item_attach->lpProps = g_new0 (struct SPropValue, 5);
-
-	flag = ATTACH_BY_VALUE; 
-	set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_ATTACH_METHOD, (const void *) (&flag));
-
-	/* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the 
-	 * attachment is not rendered using the PR_RENDERING_POSITION property. 
-	 * All values other than -1 indicate the position within PR_BODY at which 
-	 * the attachment is to be rendered. 
-	 */
-	flag = 0xFFFFFFFF;
-	set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_RENDERING_POSITION, (const void *) (&flag));
-
-	if (filename) {
-		set_SPropValue_proptag(&(item_attach->lpProps[i++]), 
-				       PR_ATTACH_FILENAME,
-				       (const void *) g_strdup(filename));
-
-		set_SPropValue_proptag(&(item_attach->lpProps[i++]), 
-				       PR_ATTACH_LONG_FILENAME, 
-				       (const void *) g_strdup(filename));
-	}
-
-	/* mime type : multipart/related */
-	content_id = camel_mime_part_get_content_id (part);
-	if (content_id) {
-		set_SPropValue_proptag(&(item_attach->lpProps[i++]), 
-				       PR_ATTACH_CONTENT_ID,
-				       (const void *) g_strdup(content_id));
-	}
-
-	item_attach->cValues = i;
-
-	stream = g_new0 (ExchangeMAPIStream, 1);
-	stream->proptag = PR_ATTACH_DATA_BIN; 
-	stream->value = g_byte_array_new ();
-
-	camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
-	while((read_size = camel_stream_read(content_stream, (char *)buf, STREAM_SIZE))){
-		stream->value = g_byte_array_append (stream->value, buf, read_size);
-	}
-
-	item_attach->streams = g_slist_append (item_attach->streams, stream); 
-	item->attachments = g_slist_append(item->attachments, item_attach);
-
-	return TRUE;
-}
+	guint64 fid = 0;
+	mapi_id_t mid = 0;
 
-static gboolean 
-mapi_do_multipart(CamelMultipart *mp, MapiItem *item)
-{
-	CamelDataWrapper *dw;
-	CamelStream *content_stream;
-	CamelContentType *type;
-	CamelMimePart *part;
-	gint n_part, i_part;
-	const gchar *filename;
-	const gchar *description;
-	const gchar *content_id;
-	gint content_size;
-
-	n_part = camel_multipart_get_number(mp);
-	for (i_part = 0; i_part < n_part; i_part++) {
-		/* getting part */
-		part = camel_multipart_get_part(mp, i_part);
-		dw = camel_medium_get_content_object (CAMEL_MEDIUM (part));
-		if (CAMEL_IS_MULTIPART(dw)) {
-			/* recursive */
-			if (!mapi_do_multipart(CAMEL_MULTIPART(dw), item))
-				return FALSE;
-			continue ;
-		}
-		/* filename */
-		filename = camel_mime_part_get_filename(part);
-
-		content_stream = camel_stream_mem_new();
-		content_size = camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content_stream);
-		camel_stream_write ((CamelStream *) content_stream, "", 1);
-
-		camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
-
-		description = camel_mime_part_get_description(part);
-		content_id = camel_mime_part_get_content_id(part);
-		
-		type = camel_mime_part_get_content_type(part);
-
-		if (i_part == 0 && camel_content_type_is (type, "text", "plain")) {
-			mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
-		} else if (camel_content_type_is (type, "text", "html")) {
-			mapi_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML);
-		} else {
-			mapi_item_add_attach (item, part, content_stream);
-		}
-	}
+	mid = exchange_mapi_create_item (olFolderOutbox, fid, NULL, NULL, 
+					 camel_mapi_utils_create_item_build_props,
+					 item, item->recipients,
+					 item->attachments, item->generic_streams, 0);
 
-	return TRUE;
+	return mid;
 }
 
-
 static gboolean
 mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
 	      CamelAddress *from, CamelAddress *recipients, CamelException *ex)
 {
-	CamelDataWrapper *dw = NULL;
-	CamelContentType *type;
-	CamelStream *content_stream;
-	CamelMultipart *multipart;
-	const CamelInternetAddress *to, *cc, *bcc;
-	MapiItem *item = g_new0 (MapiItem, 1);
+	MapiItem *item = NULL;
 	const char *namep;
 	const char *addressp;
-	const char *content_type;		
 	mapi_id_t st = 0;
-	ssize_t	content_size;
-	GSList *recipient_list = NULL;
-	GSList *attach_list = NULL;
-	gint i = 0;
-	/* headers */
 
 	if (!camel_internet_address_get((const CamelInternetAddress *)from, 0, &namep, &addressp)) {
-		printf("index\n");
 		return (FALSE);
 	}
-	/** WARNING: double check **/
-	mapi_item_set_from (item, namep);
-
-	to = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_TO);
-	for (i = 0; camel_internet_address_get(to, i, &namep, &addressp); i++){
-		mapi_item_add_recipient (addressp, olTo, &recipient_list);
-	}
-
-	cc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC);
-	for (i = 0; camel_internet_address_get(cc, i, &namep, &addressp); i++) {
-		mapi_item_add_recipient (addressp, olCC, &recipient_list);
-	}
 
-	bcc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_BCC);
-	for (i = 0; camel_internet_address_get(bcc, i, &namep, &addressp); i++) {
-		mapi_item_add_recipient (addressp, olBCC, &recipient_list);
-	}
-	
-	if (camel_mime_message_get_subject(message)) {
-		mapi_item_set_subject(item, camel_mime_message_get_subject(message));
-	}
-
-	/*Add message threading properties */
-	item->header.references = g_strdup (camel_medium_get_header ((CamelMedium *) message, "References"));
-	item->header.in_reply_to = g_strdup (camel_medium_get_header ((CamelMedium *) message, "In-Reply-To"));
-	item->header.message_id = g_strdup (camel_medium_get_header ((CamelMedium *) message, "Message-Id"));
-
-	/* contents body */
-	multipart = (CamelMultipart *)camel_medium_get_content_object (CAMEL_MEDIUM (message));
-
-	if (CAMEL_IS_MULTIPART(multipart)) {
-		if (mapi_do_multipart(CAMEL_MULTIPART(multipart), item))
-			printf("camel message multi part error\n"); 
-	} else {
-		dw = camel_medium_get_content_object (CAMEL_MEDIUM (message));
-		if (dw) {
-			type = camel_mime_part_get_content_type((CamelMimePart *)message);
-			content_type = camel_content_type_simple (type);
+	/* Convert MIME to MAPIItem, attacment lists and recipient list.*/
+	item = camel_mapi_utils_mime_to_item (message, from, recipients, ex);
 
-			content_stream = (CamelStream *)camel_stream_mem_new();
-			content_size = camel_data_wrapper_write_to_stream(dw, (CamelStream *)content_stream);
-			camel_stream_write ((CamelStream *) content_stream, "", 1);
-
-			mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
-		}
-	}
-	
 	/* send */
-	st = mapi_message_item_send(item, attach_list, recipient_list);
+	st = mapi_message_item_send(item);
 
 	if (st == 0) {
 		/*Fixme : Set a better error message. Would be helful in troubleshooting. */
@@ -395,109 +171,3 @@ camel_mapi_transport_get_type (void)
 	return camel_mapi_transport_type;
 }
 
-static gint
-mail_build_props (struct SPropValue **value, struct SPropTagArray *SPropTagArray, gpointer data)
-{
-
-	MapiItem *item = (MapiItem *) data;
-	struct SPropValue *props;
-	GSList *l;
-
-	uint32_t *msgflag = g_new0 (uint32_t, 1);
-	int i=0;
-
-	props = g_new0 (struct SPropValue, 9);
-
-	set_SPropValue_proptag(&props[i++], PR_CONVERSATION_TOPIC_UNICODE, g_strdup (item->header.subject));
-	set_SPropValue_proptag(&props[i++], PR_NORMALIZED_SUBJECT_UNICODE, g_strdup (item->header.subject));
-
-	*msgflag = MSGFLAG_UNSENT;
-	set_SPropValue_proptag(&props[i++], PR_MESSAGE_FLAGS, (void *)msgflag);
-
-	/* Message threading information */
-	if (item->header.references)
-		set_SPropValue_proptag(&props[i++], PR_INTERNET_REFERENCES, g_strdup (item->header.references));
-
-	if (item->header.in_reply_to)
-		set_SPropValue_proptag(&props[i++], PR_IN_REPLY_TO_ID, g_strdup (item->header.in_reply_to));
-
-	if (item->header.message_id)
-		set_SPropValue_proptag(&props[i++], PR_INTERNET_MESSAGE_ID, g_strdup (item->header.message_id));
-
-	for (l = item->msg.body_parts; l; l = l->next) {
-		ExchangeMAPIStream *stream = (ExchangeMAPIStream *) (l->data);
-		struct SBinary_short *bin = g_new0 (struct SBinary_short, 1);
-
-		bin->cb = stream->value->len;
-		bin->lpb = (uint8_t *)stream->value->data;
-		if (stream->proptag == PR_HTML)
-			set_SPropValue_proptag(&props[i++], stream->proptag, (void *)bin);
-		else if (stream->proptag == PR_BODY_UNICODE)
-			set_SPropValue_proptag(&props[i++], stream->proptag, (void *)stream->value->data);
-	}
-
-	/*  FIXME : */
-	/* editor = EDITOR_FORMAT_PLAINTEXT; */
-	/* set_SPropValue_proptag(&props[i++], PR_MSG_EDITOR_FORMAT, (const void *)editor); */
-
-	*value = props;
-	return i;
-}
-
-static void
-mapi_item_add_recipient (const char *recipients, OlMailRecipientType type, GSList **recipient_list)
-{
-	ExchangeMAPIRecipient *recipient;
-	uint32_t val = 0;
-	const char *str = NULL;
-
-	if (!recipients)
-		return ;
-
-	recipient = g_new0 (ExchangeMAPIRecipient, 1);
-
-	recipient->email_id = recipients;
-
-	/* this memory should be freed somewhere, perhaps in the existing
-	 * exchange_mapi_util_free_recipient_list() */
-	recipient->in.req_lpProps = g_new0 (struct SPropValue, 2);
-	recipient->in.req_cValues = 2;
-
-	set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_RECIPIENT_TYPE, (const void *) &type);
-
-	val = 0;
-	set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
-
-	/* External recipient properties - set them only when the recipient is unresolved */
-	recipient->in.ext_lpProps = g_new0 (struct SPropValue, 7);
-	recipient->in.ext_cValues = 7;
-
-	val = DT_MAILUSER;
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[0]), PR_DISPLAY_TYPE, (const void *)&val);
-	val = MAPI_MAILUSER;
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[1]), PR_OBJECT_TYPE, (const void *)&val);
-	str = "SMTP";
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[2]), PR_ADDRTYPE, (const void *)(str));
-	str = recipient->email_id;
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[3]), PR_SMTP_ADDRESS, (const void *)(str));
-	/* FIXME: Please add the correct names here instead of the e-mail ID */
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[4]), PR_GIVEN_NAME, (const void *)(str));
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[5]), PR_DISPLAY_NAME, (const void *)(str));
-	set_SPropValue_proptag (&(recipient->in.ext_lpProps[6]), PR_7BIT_DISPLAY_NAME, (const void *)(str));
-
-	*recipient_list = g_slist_append (*recipient_list, recipient);
-}
-
-/*CreateItem would return the MID of the new message or '0' if we fail.*/
-static mapi_id_t
-mapi_message_item_send (MapiItem *item, GSList *attachments, GSList *recipients)
-{
-	guint64 fid = 0;
-	mapi_id_t mid = 0;
-
-	mid = exchange_mapi_create_item (olFolderOutbox, fid, NULL, NULL, 
-					    mail_build_props, item, recipients, 
-					    item->attachments, item->generic_streams, 0);
-
-	return mid;
-}
diff --git a/src/camel/camel-mapi-utils.c b/src/camel/camel-mapi-utils.c
new file mode 100644
index 0000000..329197b
--- /dev/null
+++ b/src/camel/camel-mapi-utils.c
@@ -0,0 +1,404 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>  
+ *
+ *
+ * Authors:
+ *     Johnny Jacob <jjohnny novell com>
+ *
+ * Copyright (C) 1999-2009 Novell, Inc. (www.novell.com)
+ *
+ */
+
+
+/* -- Generate MIME to ITEM -- */
+
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/exchange.h>
+
+#include <camel/camel-data-wrapper.h>
+#include <camel/camel-exception.h>
+#include <camel/camel-mime-filter-crlf.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-session.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-stream-mem.h>
+
+#include <camel/camel-private.h>
+#include <camel/camel-i18n.h>
+#include <camel/camel-net-utils.h>
+#include <camel/camel-seekable-stream.h>
+#include <camel/camel-sasl.h>
+#include <camel/camel-utf8.h>
+#include <camel/camel-tcp-stream-raw.h>
+
+#ifdef HAVE_SSL
+#include <camel/camel-tcp-stream-ssl.h>
+#endif
+
+#include <exchange-mapi-defs.h>
+
+#include "camel-mapi-store.h"
+#include "camel-mapi-folder.h"
+#include "camel-mapi-store-summary.h"
+#include "camel-mapi-utils.h"
+
+#define d(x) x
+
+#define STREAM_SIZE 4000
+
+static void
+mapi_item_add_recipient (const char *recipients, OlMailRecipientType type, GSList **recipient_list)
+{
+	ExchangeMAPIRecipient *recipient;
+	uint32_t val = 0;
+	const char *str = NULL;
+
+	if (!recipients)
+		return ;
+
+	recipient = g_new0 (ExchangeMAPIRecipient, 1);
+
+	recipient->email_id = recipients;
+
+	/* this memory should be freed somewhere, perhaps in the existing
+	 * exchange_mapi_util_free_recipient_list() */
+	recipient->in.req_lpProps = g_new0 (struct SPropValue, 2);
+	recipient->in.req_cValues = 2;
+
+	set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_RECIPIENT_TYPE, (const void *) &type);
+
+	val = 0;
+	set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
+
+	/* External recipient properties - set them only when the recipient is unresolved */
+	recipient->in.ext_lpProps = g_new0 (struct SPropValue, 7);
+	recipient->in.ext_cValues = 7;
+
+	val = DT_MAILUSER;
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[0]), PR_DISPLAY_TYPE, (const void *)&val);
+	val = MAPI_MAILUSER;
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[1]), PR_OBJECT_TYPE, (const void *)&val);
+	str = "SMTP";
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[2]), PR_ADDRTYPE, (const void *)(str));
+	str = recipient->email_id;
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[3]), PR_SMTP_ADDRESS, (const void *)(str));
+	/* FIXME: Please add the correct names here instead of the e-mail ID */
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[4]), PR_GIVEN_NAME, (const void *)(str));
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[5]), PR_DISPLAY_NAME, (const void *)(str));
+	set_SPropValue_proptag (&(recipient->in.ext_lpProps[6]), PR_7BIT_DISPLAY_NAME, (const void *)(str));
+
+	*recipient_list = g_slist_append (*recipient_list, recipient);
+}
+
+static void
+mapi_item_set_from(MapiItem *item, const char *from)
+{
+	if (item->header.from) { 
+		free(item->header.from);
+	}
+	item->header.from = strdup(from);
+}
+
+static void
+mapi_item_set_subject(MapiItem *item, const char *subject)
+{
+	if (item->header.subject)
+		free(item->header.subject);
+
+	item->header.subject = g_strdup(subject);
+}
+
+#define MAX_READ_SIZE 0x1000
+
+static void
+mapi_item_set_body_stream (MapiItem *item, CamelStream *body, MapiItemPartType part_type)
+{
+	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
+	guint32	read_size = 0;
+	ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
+
+	camel_seekable_stream_seek((CamelSeekableStream *)body, 0, CAMEL_STREAM_SET);
+
+	stream->value = g_byte_array_new ();
+
+	while((read_size = camel_stream_read(body, (char *)buf, STREAM_SIZE))){
+		if (read_size == -1) 
+			return;
+
+		stream->value = g_byte_array_append (stream->value, buf, read_size);
+	}
+
+	switch (part_type) {
+	case PART_TYPE_TEXT_HTML :
+		stream->proptag = PR_HTML;
+		break;
+	case PART_TYPE_PLAIN_TEXT:
+		stream->proptag = PR_BODY_UNICODE;
+		break;
+	}
+
+	if (stream->value->len < MAX_READ_SIZE)
+		item->msg.body_parts = g_slist_append (item->msg.body_parts, stream);
+	else
+		item->generic_streams = g_slist_append (item->generic_streams, stream);
+
+}
+
+static gboolean
+mapi_item_add_attach (MapiItem *item, CamelMimePart *part, CamelStream *content_stream)
+{
+	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
+	const gchar *content_id = NULL;
+	guint32	read_size, flag, i = 0;
+
+	ExchangeMAPIAttachment *item_attach;
+	ExchangeMAPIStream *stream; 
+
+	const gchar *filename = camel_mime_part_get_filename (part);
+	
+	item_attach = g_new0 (ExchangeMAPIAttachment, 1);
+
+	item_attach->lpProps = g_new0 (struct SPropValue, 5);
+
+	flag = ATTACH_BY_VALUE; 
+	set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_ATTACH_METHOD, (const void *) (&flag));
+
+	/* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the 
+	 * attachment is not rendered using the PR_RENDERING_POSITION property. 
+	 * All values other than -1 indicate the position within PR_BODY at which 
+	 * the attachment is to be rendered. 
+	 */
+	flag = 0xFFFFFFFF;
+	set_SPropValue_proptag(&(item_attach->lpProps[i++]), PR_RENDERING_POSITION, (const void *) (&flag));
+
+	if (filename) {
+		set_SPropValue_proptag(&(item_attach->lpProps[i++]), 
+				       PR_ATTACH_FILENAME,
+				       (const void *) g_strdup(filename));
+
+		set_SPropValue_proptag(&(item_attach->lpProps[i++]), 
+				       PR_ATTACH_LONG_FILENAME, 
+				       (const void *) g_strdup(filename));
+	}
+
+	/* mime type : multipart/related */
+	content_id = camel_mime_part_get_content_id (part);
+	if (content_id) {
+		set_SPropValue_proptag(&(item_attach->lpProps[i++]), 
+				       PR_ATTACH_CONTENT_ID,
+				       (const void *) g_strdup(content_id));
+	}
+
+	item_attach->cValues = i;
+
+	stream = g_new0 (ExchangeMAPIStream, 1);
+	stream->proptag = PR_ATTACH_DATA_BIN; 
+	stream->value = g_byte_array_new ();
+
+	camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
+	while((read_size = camel_stream_read(content_stream, (char *)buf, STREAM_SIZE))){
+		stream->value = g_byte_array_append (stream->value, buf, read_size);
+	}
+
+	item_attach->streams = g_slist_append (item_attach->streams, stream); 
+	item->attachments = g_slist_append(item->attachments, item_attach);
+
+	return TRUE;
+}
+
+static gboolean 
+mapi_do_multipart(CamelMultipart *mp, MapiItem *item)
+{
+	CamelDataWrapper *dw;
+	CamelStream *content_stream;
+	CamelContentType *type;
+	CamelMimePart *part;
+	gint n_part, i_part;
+	const gchar *filename;
+	const gchar *description;
+	const gchar *content_id;
+	gint content_size;
+
+	n_part = camel_multipart_get_number(mp);
+	for (i_part = 0; i_part < n_part; i_part++) {
+		/* getting part */
+		part = camel_multipart_get_part(mp, i_part);
+		dw = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+		if (CAMEL_IS_MULTIPART(dw)) {
+			/* recursive */
+			if (!mapi_do_multipart(CAMEL_MULTIPART(dw), item))
+				return FALSE;
+			continue ;
+		}
+		/* filename */
+		filename = camel_mime_part_get_filename(part);
+
+		content_stream = camel_stream_mem_new();
+		content_size = camel_data_wrapper_decode_to_stream (dw, (CamelStream *) content_stream);
+		camel_stream_write ((CamelStream *) content_stream, "", 1);
+
+		camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
+
+		description = camel_mime_part_get_description(part);
+		content_id = camel_mime_part_get_content_id(part);
+		
+		type = camel_mime_part_get_content_type(part);
+
+		if (i_part == 0 && camel_content_type_is (type, "text", "plain")) {
+			mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+		} else if (camel_content_type_is (type, "text", "html")) {
+			mapi_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML);
+		} else {
+			mapi_item_add_attach (item, part, content_stream);
+		}
+	}
+
+	return TRUE;
+}
+
+
+MapiItem *
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, CamelAddress *recipients,
+			       CamelException *ex)
+{
+	CamelDataWrapper *dw = NULL;
+	CamelContentType *type;
+	CamelStream *content_stream;
+	CamelMultipart *multipart;
+	const CamelInternetAddress *to, *cc, *bcc;
+	MapiItem *item = g_new0 (MapiItem, 1);
+	const char *namep;
+	const char *addressp;
+	const char *content_type;		
+
+	ssize_t	content_size;
+	GSList *recipient_list = NULL;
+	gint i = 0;
+
+	/* headers */
+
+	if (!camel_internet_address_get((const CamelInternetAddress *)from, 0, &namep, &addressp)) {
+		printf("index\n");
+		return (FALSE);
+	}
+
+	/** WARNING: double check **/
+	mapi_item_set_from (item, namep);
+
+	to = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_TO);
+	for (i = 0; camel_internet_address_get(to, i, &namep, &addressp); i++){
+		mapi_item_add_recipient (addressp, olTo, &recipient_list);
+	}
+
+	cc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC);
+	for (i = 0; camel_internet_address_get(cc, i, &namep, &addressp); i++) {
+		mapi_item_add_recipient (addressp, olCC, &recipient_list);
+	}
+
+	bcc = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_BCC);
+	for (i = 0; camel_internet_address_get(bcc, i, &namep, &addressp); i++) {
+		mapi_item_add_recipient (addressp, olBCC, &recipient_list);
+	}
+	
+	if (camel_mime_message_get_subject(message)) {
+		mapi_item_set_subject(item, camel_mime_message_get_subject(message));
+	}
+
+	/*Add message threading properties */
+	item->header.references = g_strdup (camel_medium_get_header ((CamelMedium *) message, "References"));
+	item->header.in_reply_to = g_strdup (camel_medium_get_header ((CamelMedium *) message, "In-Reply-To"));
+	item->header.message_id = g_strdup (camel_medium_get_header ((CamelMedium *) message, "Message-Id"));
+
+	/* contents body */
+	multipart = (CamelMultipart *)camel_medium_get_content_object (CAMEL_MEDIUM (message));
+
+	if (CAMEL_IS_MULTIPART(multipart)) {
+		if (mapi_do_multipart(CAMEL_MULTIPART(multipart), item))
+			printf("camel message multi part error\n"); 
+	} else {
+		dw = camel_medium_get_content_object (CAMEL_MEDIUM (message));
+		if (dw) {
+			type = camel_mime_part_get_content_type((CamelMimePart *)message);
+			content_type = camel_content_type_simple (type);
+
+			content_stream = (CamelStream *)camel_stream_mem_new();
+			content_size = camel_data_wrapper_write_to_stream(dw, (CamelStream *)content_stream);
+			camel_stream_write ((CamelStream *) content_stream, "", 1);
+
+			mapi_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT);
+		}
+	}
+
+	item->attachments = attach_list;
+	item->recipients = recipient_list;
+	
+	return item;
+}
+
+gint
+camel_mapi_utils_create_item_build_props (struct SPropValue **value, struct SPropTagArray *SPropTagArray, gpointer data)
+{
+
+	MapiItem *item = (MapiItem *) data;
+	struct SPropValue *props;
+	GSList *l;
+
+	uint32_t *msgflag = g_new0 (uint32_t, 1);
+	int i=0;
+
+	props = g_new0 (struct SPropValue, 9);
+
+	set_SPropValue_proptag(&props[i++], PR_CONVERSATION_TOPIC_UNICODE, g_strdup (item->header.subject));
+	set_SPropValue_proptag(&props[i++], PR_NORMALIZED_SUBJECT_UNICODE, g_strdup (item->header.subject));
+
+	*msgflag = MSGFLAG_UNSENT;
+	set_SPropValue_proptag(&props[i++], PR_MESSAGE_FLAGS, (void *)msgflag);
+
+	/* Message threading information */
+	if (item->header.references)
+		set_SPropValue_proptag(&props[i++], PR_INTERNET_REFERENCES, g_strdup (item->header.references));
+
+	if (item->header.in_reply_to)
+		set_SPropValue_proptag(&props[i++], PR_IN_REPLY_TO_ID, g_strdup (item->header.in_reply_to));
+
+	if (item->header.message_id)
+		set_SPropValue_proptag(&props[i++], PR_INTERNET_MESSAGE_ID, g_strdup (item->header.message_id));
+
+	for (l = item->msg.body_parts; l; l = l->next) {
+		ExchangeMAPIStream *stream = (ExchangeMAPIStream *) (l->data);
+		struct SBinary_short *bin = g_new0 (struct SBinary_short, 1);
+
+		bin->cb = stream->value->len;
+		bin->lpb = (uint8_t *)stream->value->data;
+		if (stream->proptag == PR_HTML)
+			set_SPropValue_proptag(&props[i++], stream->proptag, (void *)bin);
+		else if (stream->proptag == PR_BODY_UNICODE)
+			set_SPropValue_proptag(&props[i++], stream->proptag, (void *)stream->value->data);
+	}
+
+	/*  FIXME : */
+	/* editor = EDITOR_FORMAT_PLAINTEXT; */
+	/* set_SPropValue_proptag(&props[i++], PR_MSG_EDITOR_FORMAT, (const void *)editor); */
+
+	*value = props;
+	return i;
+}
+
+/* -- Generate MIME to ITEM -- */
diff --git a/src/camel/camel-mapi-utils.h b/src/camel/camel-mapi-utils.h
new file mode 100644
index 0000000..ca200ad
--- /dev/null
+++ b/src/camel/camel-mapi-utils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>  
+ *
+ *
+ * Authors:
+ *     Johnny Jacob <jjohnny novell com>
+ *
+ * Copyright (C) 1999-2009 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __CAMEL_MAPI_UTILS_H__
+#define __CAMEL_MAPI_UTILS_H__
+
+G_BEGIN_DECLS
+
+MapiItem *
+camel_mapi_utils_mime_to_item (CamelMimeMessage *message, CamelAddress *from, 
+			       CamelAddress *recipients, CamelException *ex);
+
+gint
+camel_mapi_utils_create_item_build_props (struct SPropValue **value, 
+					  struct SPropTagArray *SPropTagArray,
+					  gpointer data);
+
+G_END_DECLS
+
+#endif /* CAMEL_MAPI_UTILS_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]