aboutsummaryrefslogtreecommitdiffstats
path: root/em-format
diff options
context:
space:
mode:
Diffstat (limited to 'em-format')
-rw-r--r--em-format/e-mail-parser-application-mbox.c37
-rw-r--r--em-format/e-mail-parser-application-smime.c59
-rw-r--r--em-format/e-mail-parser-attachment-bar.c13
-rw-r--r--em-format/e-mail-parser-extension.c48
-rw-r--r--em-format/e-mail-parser-extension.h10
-rw-r--r--em-format/e-mail-parser-headers.c12
-rw-r--r--em-format/e-mail-parser-image.c23
-rw-r--r--em-format/e-mail-parser-inlinepgp-encrypted.c64
-rw-r--r--em-format/e-mail-parser-inlinepgp-signed.c57
-rw-r--r--em-format/e-mail-parser-message-deliverystatus.c19
-rw-r--r--em-format/e-mail-parser-message-external.c12
-rw-r--r--em-format/e-mail-parser-message-rfc822.c42
-rw-r--r--em-format/e-mail-parser-message.c33
-rw-r--r--em-format/e-mail-parser-multipart-alternative.c32
-rw-r--r--em-format/e-mail-parser-multipart-appledouble.c33
-rw-r--r--em-format/e-mail-parser-multipart-digest.c62
-rw-r--r--em-format/e-mail-parser-multipart-encrypted.c95
-rw-r--r--em-format/e-mail-parser-multipart-mixed.c74
-rw-r--r--em-format/e-mail-parser-multipart-related.c50
-rw-r--r--em-format/e-mail-parser-multipart-signed.c100
-rw-r--r--em-format/e-mail-parser-secure-button.c9
-rw-r--r--em-format/e-mail-parser-source.c12
-rw-r--r--em-format/e-mail-parser-text-enriched.c23
-rw-r--r--em-format/e-mail-parser-text-html.c31
-rw-r--r--em-format/e-mail-parser-text-plain.c75
-rw-r--r--em-format/e-mail-parser.c105
-rw-r--r--em-format/e-mail-parser.h19
27 files changed, 556 insertions, 593 deletions
diff --git a/em-format/e-mail-parser-application-mbox.c b/em-format/e-mail-parser-application-mbox.c
index fb901afdea..35eedf9a5e 100644
--- a/em-format/e-mail-parser-application-mbox.c
+++ b/em-format/e-mail-parser-application-mbox.c
@@ -60,24 +60,21 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "application/mbox",
NULL };
-static GSList *
+static gboolean
empe_app_mbox_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMimeParser *mime_parser;
CamelStream *mem_stream;
camel_mime_parser_state_t state;
gint old_len;
gint messages;
- GSList *parts;
GError *error = NULL;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
/* Extract messages from the application/mbox part and
* render them as a flat list of messages. */
@@ -103,14 +100,14 @@ empe_app_mbox_parse (EMailParserExtension *extension,
camel_mime_parser_init_with_stream (mime_parser, mem_stream, &error);
if (error != NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Error parsing MBOX part: %s"),
error->message);
g_object_unref (mem_stream);
g_object_unref (mime_parser);
g_error_free (error);
- return parts;
+ return TRUE;
}
g_object_unref (mem_stream);
@@ -121,11 +118,10 @@ empe_app_mbox_parse (EMailParserExtension *extension,
messages = 0;
state = camel_mime_parser_step (mime_parser, NULL, NULL);
- parts = NULL;
while (state == CAMEL_MIME_PARSER_STATE_FROM) {
+ GQueue work_queue = G_QUEUE_INIT;
CamelMimeMessage *message;
CamelMimePart *opart;
- GSList *new_parts;
message = camel_mime_message_new ();
opart = CAMEL_MIME_PART (message);
@@ -142,23 +138,22 @@ empe_app_mbox_parse (EMailParserExtension *extension,
camel_medium_set_content (CAMEL_MEDIUM (opart), CAMEL_DATA_WRAPPER (message));
camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (opart), "message/rfc822");
- new_parts = e_mail_parser_parse_part_as (
- parser, opart,
- part_id, "message/rfc822", cancellable);
+ e_mail_parser_parse_part_as (
+ parser, opart, part_id, "message/rfc822",
+ cancellable, &work_queue);
/* Wrap every message as attachment */
- new_parts = e_mail_parser_wrap_as_attachment (
- parser, opart,
- new_parts, part_id, cancellable);
+ e_mail_parser_wrap_as_attachment (
+ parser, opart, part_id, &work_queue);
/* Inline all messages in mbox */
- if (new_parts && new_parts->data) {
- EMailPart *p = new_parts->data;
+ if (!g_queue_is_empty (&work_queue)) {
+ EMailPart *p = g_queue_peek_head (&work_queue);
p->force_inline = TRUE;
}
- parts = g_slist_concat (parts, new_parts);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, old_len);
@@ -175,7 +170,7 @@ empe_app_mbox_parse (EMailParserExtension *extension,
g_object_unref (mime_parser);
- return parts;
+ return TRUE;
}
static guint32
diff --git a/em-format/e-mail-parser-application-smime.c b/em-format/e-mail-parser-application-smime.c
index 9fbf24e3ff..919af9d1f2 100644
--- a/em-format/e-mail-parser-application-smime.c
+++ b/em-format/e-mail-parser-application-smime.c
@@ -65,28 +65,25 @@ static const gchar * parser_mime_types[] = { "application/xpkcs7mime",
"application/x-pkcs7-signature",
NULL };
-static GSList *
+static gboolean
empe_app_smime_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelCipherContext *context;
CamelMimePart *opart;
CamelCipherValidity *valid;
GError *local_error = NULL;
- GSList *parts, *iter;
CamelContentType *ct;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
ct = camel_mime_part_get_content_type (part);
if (camel_content_type_is (ct, "application", "pkcs7-signature") ||
camel_content_type_is (ct, "application", "xpkcs7-signature") ||
camel_content_type_is (ct, "application", "x-pkcs7-signature")) {
- return g_slist_alloc ();
+ return TRUE;
}
context = camel_smime_context_new (e_mail_parser_get_session (parser));
@@ -99,58 +96,60 @@ empe_app_smime_parse (EMailParserExtension *extension,
e_mail_part_preserve_charset_in_content_type (part, opart);
if (local_error != NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Could not parse S/MIME message: %s"),
local_error->message);
g_error_free (local_error);
} else {
+ GQueue work_queue = G_QUEUE_INIT;
+ GList *head, *link;
gint len = part_id->len;
g_string_append (part_id, ".encrypted");
- parts = e_mail_parser_parse_part (
- parser, opart, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, opart, part_id, cancellable, &work_queue);
g_string_truncate (part_id, len);
- /* Update validity flags of all the involved subp-arts */
- for (iter = parts; iter; iter = iter->next) {
+ head = g_queue_peek_head_link (&work_queue);
- EMailPart *mail_part = iter->data;
- if (!mail_part)
- continue;
+ /* Update validity flags of all the involved subp-arts */
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
e_mail_part_update_validity (
mail_part, valid,
E_MAIL_PART_VALIDITY_ENCRYPTED |
E_MAIL_PART_VALIDITY_SMIME);
-
}
- /* Add a widget with details about the encryption, but only when
- * the encrypted isn't itself secured, in that case it has created
- * the button itself */
+ e_queue_transfer (&work_queue, out_mail_parts);
+
+ /* Add a widget with details about the encryption, but only
+ * when the encrypted isn't itself secured, in that case it
+ * has created the button itself. */
if (!e_mail_part_is_secured (opart)) {
- GSList *button;
EMailPart *mail_part;
+
g_string_append (part_id, ".encrypted.button");
- button = e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.widget.secure-button",
- cancellable);
- if (button && button->data) {
- mail_part = button->data;
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.widget.secure-button",
+ cancellable, &work_queue);
+
+ mail_part = g_queue_peek_head (&work_queue);
+ if (mail_part != NULL)
e_mail_part_update_validity (
mail_part, valid,
E_MAIL_PART_VALIDITY_ENCRYPTED |
E_MAIL_PART_VALIDITY_SMIME);
- }
- parts = g_slist_concat (parts, button);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, len);
}
@@ -161,7 +160,7 @@ empe_app_smime_parse (EMailParserExtension *extension,
g_object_unref (opart);
g_object_unref (context);
- return parts;
+ return TRUE;
}
static guint32
diff --git a/em-format/e-mail-parser-attachment-bar.c b/em-format/e-mail-parser-attachment-bar.c
index 5df1afa7a1..f8c45fb327 100644
--- a/em-format/e-mail-parser-attachment-bar.c
+++ b/em-format/e-mail-parser-attachment-bar.c
@@ -67,12 +67,13 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar *parser_mime_types[] = { "application/vnd.evolution.widget.attachment-bar", NULL };
-static GSList *
+static gboolean
empe_attachment_bar_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailPartAttachmentBar *empab;
gint len;
@@ -80,13 +81,15 @@ empe_attachment_bar_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append (part_id, ".attachment-bar");
empab = (EMailPartAttachmentBar *) e_mail_part_subclass_new (
- part, part_id->str, sizeof (EMailPartAttachmentBar),
- (GFreeFunc) mail_part_attachment_bar_free);
+ part, part_id->str, sizeof (EMailPartAttachmentBar),
+ (GFreeFunc) mail_part_attachment_bar_free);
empab->parent.mime_type = g_strdup ("application/vnd.evolution.widget.attachment-bar");
empab->store = E_ATTACHMENT_STORE (e_attachment_store_new ());
g_string_truncate (part_id, len);
- return g_slist_append (NULL, empab);
+ g_queue_push_tail (out_mail_parts, empab);
+
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-extension.c b/em-format/e-mail-parser-extension.c
index 72f1fd8445..df8fc54dcb 100644
--- a/em-format/e-mail-parser-extension.c
+++ b/em-format/e-mail-parser-extension.c
@@ -52,18 +52,20 @@ e_mail_parser_extension_default_init (EMailParserExtensionInterface *interface)
* @part_id: a #GString to which parser will append ID of the parsed part.
* @flags: #EMailParserFlags
* @cancellable: (allow-none) A #GCancellable
+ * @out_mail_parts: a #GQueue to deposit #EMailPart instances
*
* A virtual function reimplemented in all mail parser extensions. The function
- * decodes and parses the @mime_part, creating one or more #EMailPart<!-//>s.
+ * decodes and parses the @mime_part, appending one or more #EMailPart<!-//>s
+ * to the @out_mail_parts queue.
*
- * When the function is unable to parse the @mime_part (either because it's broken
- * or because it is a different mimetype then the extension is specialized for), the
- * function will return @NULL indicating the #EMailParser, that it should pick
- * another extension.
+ * When the function is unable to parse the @mime_part (either because it's
+ * broken or because it is a different MIME type then the extension is
+ * specialized for), the function will return %FALSE to indicate to the
+ * #EMailParser that it should pick another extension.
*
- * When the @mime_part contains for example multipart/mixed of one RFC822 message
- * with an attachment and of one image, then parser must make sure that the
- * returned #GSList is correctly ordered:
+ * When the @mime_part contains for example multipart/mixed of one RFC822
+ * message with an attachment and of one image, then parser must make sure
+ * that parts are appeded to @out_mail_parts in the correct order.
*
* part1.rfc822.plain_text
* part1.rfc822.attachment
@@ -71,25 +73,33 @@ e_mail_parser_extension_default_init (EMailParserExtensionInterface *interface)
*
* Implementation of this function must be thread-safe.
*
- * Return value: Returns #GSList of #EMailPart<!-//>s when the part was succesfully
- * parsed, returns @NULL when the parser is not able to parse the part.
+ * Returns: %TRUE if the @mime_part was handled (even if no
+ * #EMailPart<!-//>s were added to @out_mail_parts), or
+ * %FALSE if the @mime_part was not handled
*/
-GSList *
+gboolean
e_mail_parser_extension_parse (EMailParserExtension *extension,
- EMailParser *parser,
- CamelMimePart *mime_part,
- GString *part_id,
- GCancellable *cancellable)
+ EMailParser *parser,
+ CamelMimePart *mime_part,
+ GString *part_id,
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailParserExtensionInterface *interface;
- g_return_val_if_fail (E_IS_MAIL_PARSER_EXTENSION (extension), NULL);
- g_return_val_if_fail (E_IS_MAIL_PARSER (parser), NULL);
+ g_return_val_if_fail (E_IS_MAIL_PARSER_EXTENSION (extension), FALSE);
+ g_return_val_if_fail (E_IS_MAIL_PARSER (parser), FALSE);
interface = E_MAIL_PARSER_EXTENSION_GET_INTERFACE (extension);
- g_return_val_if_fail (interface->parse != NULL, NULL);
+ g_return_val_if_fail (interface->parse != NULL, FALSE);
- return interface->parse (extension, parser, mime_part, part_id, cancellable);
+ /* Check for cancellation before calling the method. */
+ if (g_cancellable_is_cancelled (cancellable))
+ return FALSE;
+
+ return interface->parse (
+ extension, parser, mime_part, part_id,
+ cancellable, out_mail_parts);
}
guint32
diff --git a/em-format/e-mail-parser-extension.h b/em-format/e-mail-parser-extension.h
index 101c1320dc..e5acece68e 100644
--- a/em-format/e-mail-parser-extension.h
+++ b/em-format/e-mail-parser-extension.h
@@ -68,11 +68,12 @@ typedef enum {
struct _EMailParserExtensionInterface {
EMailExtensionInterface parent_interface;
- GSList * (*parse) (EMailParserExtension *extension,
+ gboolean (*parse) (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *mime_part,
GString *part_id,
- GCancellable *cancellable);
+ GCancellable *cancellable,
+ GQueue *out_mail_parts);
guint32 (*get_flags) (EMailParserExtension *extension);
@@ -80,11 +81,12 @@ struct _EMailParserExtensionInterface {
GType e_mail_parser_extension_get_type
(void) G_GNUC_CONST;
-GSList * e_mail_parser_extension_parse (EMailParserExtension *extension,
+gboolean e_mail_parser_extension_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *mime_part,
GString *part_id,
- GCancellable *cancellable);
+ GCancellable *cancellable,
+ GQueue *out_mail_parts);
guint32 e_mail_parser_extension_get_flags
(EMailParserExtension *extension);
diff --git a/em-format/e-mail-parser-headers.c b/em-format/e-mail-parser-headers.c
index c66563aef1..edb6de4407 100644
--- a/em-format/e-mail-parser-headers.c
+++ b/em-format/e-mail-parser-headers.c
@@ -88,19 +88,17 @@ empe_headers_bind_dom (EMailPart *part,
g_free (uri);
}
-static GSList *
+static gboolean
empe_headers_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailPart *mail_part;
gint len;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
len = part_id->len;
g_string_append (part_id, ".headers");
@@ -109,7 +107,9 @@ empe_headers_parse (EMailParserExtension *extension,
mail_part->bind_func = empe_headers_bind_dom;
g_string_truncate (part_id, len);
- return g_slist_append (NULL, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
+
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-image.c b/em-format/e-mail-parser-image.c
index b252714215..12242746f2 100644
--- a/em-format/e-mail-parser-image.c
+++ b/em-format/e-mail-parser-image.c
@@ -71,22 +71,21 @@ static const gchar *parser_mime_types[] = { "image/gif",
"image/pjpeg",
NULL };
-static GSList *
+static gboolean
empe_image_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
+ GQueue work_queue = G_QUEUE_INIT;
EMailPart *mail_part;
const gchar *tmp;
gchar *cid;
gint len;
CamelContentType *ct;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
tmp = camel_mime_part_get_content_id (part);
if (tmp) {
cid = g_strdup_printf ("cid:%s", tmp);
@@ -107,13 +106,15 @@ empe_image_parse (EMailParserExtension *extension,
g_string_truncate (part_id, len);
- if (!cid) {
- return e_mail_parser_wrap_as_attachment (
- parser, part, g_slist_append (NULL, mail_part),
- part_id, cancellable);
- }
+ g_queue_push_tail (&work_queue, mail_part);
+
+ if (cid == NULL)
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
- return g_slist_append (NULL, mail_part);
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-inlinepgp-encrypted.c b/em-format/e-mail-parser-inlinepgp-encrypted.c
index 3a61a5eeff..ce3f372cc1 100644
--- a/em-format/e-mail-parser-inlinepgp-encrypted.c
+++ b/em-format/e-mail-parser-inlinepgp-encrypted.c
@@ -58,12 +58,13 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "application/x-inlinepgp-encrypted",
NULL };
-static GSList *
+static gboolean
empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelCipherContext *cipher;
CamelCipherValidity *valid;
@@ -71,11 +72,9 @@ empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
CamelDataWrapper *dw;
gchar *mime_type;
gint len;
+ GQueue work_queue = G_QUEUE_INIT;
+ GList *head, *link;
GError *local_error = NULL;
- GSList *parts, *iter;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
cipher = camel_gpg_context_new (e_mail_parser_get_session (parser));
@@ -86,22 +85,21 @@ empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
cipher, part, opart, cancellable, &local_error);
if (local_error != NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Could not parse PGP message: %s"),
local_error->message);
g_error_free (local_error);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (parser,
- part, part_id,
- "application/vnd.evolution.source",
- cancellable));
+ e_mail_parser_parse_part_as (parser,
+ part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
g_object_unref (cipher);
g_object_unref (opart);
- return parts;
+
+ return TRUE;
}
dw = camel_medium_get_content ((CamelMedium *) opart);
@@ -122,18 +120,17 @@ empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append (part_id, ".inlinepgp_encrypted");
- parts = e_mail_parser_parse_part_as (
- parser, opart, part_id,
- camel_data_wrapper_get_mime_type (dw), cancellable);
+ e_mail_parser_parse_part_as (
+ parser, opart, part_id,
+ camel_data_wrapper_get_mime_type (dw),
+ cancellable, &work_queue);
g_string_truncate (part_id, len);
- for (iter = parts; iter; iter = iter->next) {
- EMailPart *mail_part;
+ head = g_queue_peek_head_link (&work_queue);
- mail_part = iter->data;
- if (!mail_part)
- continue;
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
e_mail_part_update_validity (
mail_part, valid,
@@ -141,28 +138,29 @@ empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
E_MAIL_PART_VALIDITY_PGP);
}
+ e_queue_transfer (&work_queue, out_mail_parts);
+
/* Add a widget with details about the encryption, but only when
* the encrypted isn't itself secured, in that case it has created
* the button itself */
if (!e_mail_part_is_secured (opart)) {
- GSList *button;
EMailPart *mail_part;
+
g_string_append (part_id, ".inlinepgp_encrypted.button");
- button = e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.widget.secure-button",
- cancellable);
- if (button && button->data) {
- mail_part = button->data;
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.widget.secure-button",
+ cancellable, &work_queue);
+ mail_part = g_queue_peek_head (&work_queue);
+ if (mail_part != NULL)
e_mail_part_update_validity (
mail_part, valid,
E_MAIL_PART_VALIDITY_ENCRYPTED |
E_MAIL_PART_VALIDITY_PGP);
- }
- parts = g_slist_concat (parts, button);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, len);
}
@@ -172,7 +170,7 @@ empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
g_object_unref (opart);
g_object_unref (cipher);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-inlinepgp-signed.c b/em-format/e-mail-parser-inlinepgp-signed.c
index 23461299d9..723acc23cf 100644
--- a/em-format/e-mail-parser-inlinepgp-signed.c
+++ b/em-format/e-mail-parser-inlinepgp-signed.c
@@ -58,12 +58,13 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "application/x-inlinepgp-signed",
NULL };
-static GSList *
+static gboolean
empe_inlinepgp_signed_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelStream *filtered_stream;
CamelMimeFilterPgp *pgp_filter;
@@ -73,14 +74,12 @@ empe_inlinepgp_signed_parse (EMailParserExtension *extension,
CamelDataWrapper *dw;
CamelMimePart *opart;
CamelStream *ostream;
+ GQueue work_queue = G_QUEUE_INIT;
+ GList *head, *link;
gchar *type;
gint len;
GError *local_error = NULL;
GByteArray *ba;
- GSList *parts, *iter;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
cipher = camel_gpg_context_new (e_mail_parser_get_session (parser));
@@ -89,22 +88,21 @@ empe_inlinepgp_signed_parse (EMailParserExtension *extension,
cipher, part, cancellable, &local_error);
if (local_error != NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Error verifying signature: %s"),
local_error->message);
g_error_free (local_error);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source",
- cancellable));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
g_object_unref (cipher);
- return parts;
+
+ return TRUE;
}
/* Setup output stream */
@@ -147,15 +145,13 @@ empe_inlinepgp_signed_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append (part_id, ".inlinepgp_signed");
- parts = e_mail_parser_parse_part (
- parser, opart, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, opart, part_id, cancellable, &work_queue);
- for (iter = parts; iter; iter = iter->next) {
- EMailPart *mail_part;
+ head = g_queue_peek_head_link (&work_queue);
- mail_part = iter->data;
- if (!mail_part)
- continue;
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
e_mail_part_update_validity (
mail_part, valid,
@@ -163,30 +159,31 @@ empe_inlinepgp_signed_parse (EMailParserExtension *extension,
E_MAIL_PART_VALIDITY_PGP);
}
+ e_queue_transfer (&work_queue, out_mail_parts);
+
g_string_truncate (part_id, len);
/* Add a widget with details about the encryption, but only when
* the encrypted isn't itself secured, in that case it has created
* the button itself */
if (!e_mail_part_is_secured (opart)) {
- GSList *button;
EMailPart *mail_part;
+
g_string_append (part_id, ".inlinepgp_signed.button");
- button = e_mail_parser_parse_part_as (
+ e_mail_parser_parse_part_as (
parser, part, part_id,
"application/vnd.evolution.widget.secure-button",
- cancellable);
- if (button && button->data) {
- mail_part = button->data;
+ cancellable, &work_queue);
+ mail_part = g_queue_peek_head (&work_queue);
+ if (mail_part != NULL)
e_mail_part_update_validity (
mail_part, valid,
E_MAIL_PART_VALIDITY_SIGNED |
E_MAIL_PART_VALIDITY_PGP);
- }
- parts = g_slist_concat (parts, button);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, len);
}
@@ -197,7 +194,7 @@ empe_inlinepgp_signed_parse (EMailParserExtension *extension,
g_object_unref (ostream);
g_object_unref (cipher);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-message-deliverystatus.c b/em-format/e-mail-parser-message-deliverystatus.c
index 3a86a9380e..f219a9745c 100644
--- a/em-format/e-mail-parser-message-deliverystatus.c
+++ b/em-format/e-mail-parser-message-deliverystatus.c
@@ -60,19 +60,18 @@ static const gchar * parser_mime_types[] = { "message/delivery-status",
"message/disposition-notification",
NULL };
-static GSList *
+static gboolean
empe_msg_deliverystatus_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
+ GQueue work_queue = G_QUEUE_INIT;
EMailPart *mail_part;
gsize len;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
len = part_id->len;
g_string_append (part_id, ".delivery-status");
mail_part = e_mail_part_new (part, part_id->str);
@@ -80,11 +79,15 @@ empe_msg_deliverystatus_parse (EMailParserExtension *extension,
g_string_truncate (part_id, len);
+ g_queue_push_tail (&work_queue, mail_part);
+
/* The only reason for having a separate parser for
* message/delivery-status is to display the part as an attachment */
- return e_mail_parser_wrap_as_attachment (
- parser, part, g_slist_append (NULL, mail_part),
- part_id, cancellable);
+ e_mail_parser_wrap_as_attachment (parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
+
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-message-external.c b/em-format/e-mail-parser-message-external.c
index 99b6b8bd57..5768e6e34c 100644
--- a/em-format/e-mail-parser-message-external.c
+++ b/em-format/e-mail-parser-message-external.c
@@ -58,12 +58,13 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "message/external-body",
NULL };
-static GSList *
+static gboolean
empe_msg_external_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailPart *mail_part;
CamelMimePart *newpart;
@@ -74,9 +75,6 @@ empe_msg_external_parse (EMailParserExtension *extension,
gint len;
gchar *mime_type;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
newpart = camel_mime_part_new ();
/* needs to be cleaner */
@@ -177,7 +175,9 @@ addPart:
mail_part->mime_type = mime_type;
g_string_truncate (part_id, len);
- return g_slist_append (NULL, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
+
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-message-rfc822.c b/em-format/e-mail-parser-message-rfc822.c
index 4632c6e0eb..70bf8c89ed 100644
--- a/em-format/e-mail-parser-message-rfc822.c
+++ b/em-format/e-mail-parser-message-rfc822.c
@@ -62,14 +62,14 @@ static const gchar * parser_mime_types[] = { "message/rfc822",
"message/news",
NULL };
-static GSList *
+static gboolean
empe_msg_rfc822_parse (EMailParserExtension *extension,
EMailParser *eparser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
- GSList *parts = NULL;
EMailPart *mail_part;
gint len;
CamelMimePart *message;
@@ -81,13 +81,14 @@ empe_msg_rfc822_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append (part_id, ".rfc822");
- /* Create an empty PURI that will represent start of the RFC message */
+ /* Create an empty PURI that will represent start of the RFC message */
mail_part = e_mail_part_new (part, part_id->str);
mail_part->mime_type = g_strdup ("message/rfc822");
- parts = g_slist_append (NULL, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
- /* Sometime the _actual_ message is encapsulated in another CamelMimePart,
- * sometimes the CamelMimePart actually represents the RFC822 message */
+ /* Sometime the actual message is encapsulated in another
+ * CamelMimePart, sometimes the CamelMimePart itself represents
+ * the RFC822 message. */
ct = camel_mime_part_get_content_type (part);
if (camel_content_type_is (ct, "message", "rfc822")) {
new_stream = camel_stream_mem_new ();
@@ -110,28 +111,29 @@ empe_msg_rfc822_parse (EMailParserExtension *extension,
message = g_object_ref (part);
}
- parts = g_slist_concat (parts, e_mail_parser_parse_part_as (
- eparser, message, part_id,
- "application/vnd.evolution.message",
- cancellable));
+ e_mail_parser_parse_part_as (
+ eparser, message, part_id,
+ "application/vnd.evolution.message",
+ cancellable, out_mail_parts);
g_object_unref (message);
- /* Add another generic EMailPart that represents end of the RFC message.
- * The em_format_write() function will skip all parts between the ".rfc822"
- * part and ".rfc822.end" part as they will be rendered in an <iframe> */
+ /* Add another generic EMailPart that represents end of the RFC
+ * message. The em_format_write() function will skip all parts
+ * between the ".rfc822" part and ".rfc822.end" part as they will
+ * be rendered in an <iframe>. */
g_string_append (part_id, ".end");
mail_part = e_mail_part_new (message, part_id->str);
mail_part->is_hidden = TRUE;
- parts = g_slist_append (parts, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
+
g_string_truncate (part_id, len);
- if (e_mail_part_is_attachment (message)) {
- return e_mail_parser_wrap_as_attachment (
- eparser, message, parts, part_id, cancellable);
- }
+ if (e_mail_part_is_attachment (message))
+ e_mail_parser_wrap_as_attachment (
+ eparser, message, part_id, out_mail_parts);
- return parts;
+ return TRUE;
}
static guint32
diff --git a/em-format/e-mail-parser-message.c b/em-format/e-mail-parser-message.c
index 7b6e6201d5..df7d4b3320 100644
--- a/em-format/e-mail-parser-message.c
+++ b/em-format/e-mail-parser-message.c
@@ -59,31 +59,28 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar *parser_mime_types[] = { "application/vnd.evolution.message", NULL };
-static GSList *
+static gboolean
empe_message_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
- GSList *parts;
CamelContentType *ct;
gchar *mime_type;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
/* Headers */
- parts = g_slist_concat (NULL, e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.headers",
- cancellable));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.headers",
+ cancellable, out_mail_parts);
/* Attachment Bar */
- parts = g_slist_concat (parts, e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.widget.attachment-bar",
- cancellable));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.widget.attachment-bar",
+ cancellable, out_mail_parts);
ct = camel_mime_part_get_content_type (part);
mime_type = camel_content_type_simple (ct);
@@ -103,13 +100,13 @@ empe_message_parse (EMailParserExtension *extension,
}
/* Actual message body */
- parts = g_slist_concat (parts, e_mail_parser_parse_part_as (
- parser, part, part_id, mime_type,
- cancellable));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, mime_type,
+ cancellable, out_mail_parts);
g_free (mime_type);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-multipart-alternative.c b/em-format/e-mail-parser-multipart-alternative.c
index 74826da814..de4261bf0c 100644
--- a/em-format/e-mail-parser-multipart-alternative.c
+++ b/em-format/e-mail-parser-multipart-alternative.c
@@ -65,32 +65,28 @@ related_display_part_is_attachment (CamelMimePart *part)
return display_part && e_mail_part_is_attachment (display_part);
}
-static GSList *
+static gboolean
empe_mp_alternative_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMultipart *mp;
gint i, nparts, bestid = 0;
CamelMimePart *best = NULL;
- GSList *parts;
EMailExtensionRegistry *reg;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
reg = e_mail_parser_get_extension_registry (parser);
mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
- if (!CAMEL_IS_MULTIPART (mp)) {
+ if (!CAMEL_IS_MULTIPART (mp))
return e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source",
- cancellable);
- }
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
/* as per rfc, find the last part we know how to display */
nparts = camel_multipart_get_number (mp);
@@ -103,7 +99,7 @@ empe_mp_alternative_parse (EMailParserExtension *extension,
gsize content_size;
if (g_cancellable_is_cancelled (cancellable))
- return NULL;
+ return TRUE;
/* is it correct to use the passed in *part here? */
mpart = camel_multipart_get_part (mp, i);
@@ -148,16 +144,18 @@ empe_mp_alternative_parse (EMailParserExtension *extension,
g_string_append_printf (part_id, ".alternative.%d", bestid);
- parts = e_mail_parser_parse_part (
- parser, best, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, best, part_id,
+ cancellable, out_mail_parts);
g_string_truncate (part_id, len);
} else {
- parts = e_mail_parser_parse_part_as (
- parser, part, part_id, "multipart/mixed", cancellable);
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, "multipart/mixed",
+ cancellable, out_mail_parts);
}
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-multipart-appledouble.c b/em-format/e-mail-parser-multipart-appledouble.c
index f8e1cf390f..297ded6243 100644
--- a/em-format/e-mail-parser-multipart-appledouble.c
+++ b/em-format/e-mail-parser-multipart-appledouble.c
@@ -52,26 +52,23 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "multipart/appledouble", NULL };
-static GSList *
+static gboolean
empe_mp_appledouble_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMultipart *mp;
- GSList *parts;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
if (!CAMEL_IS_MULTIPART (mp)) {
- parts = e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source",
- cancellable);
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
} else {
CamelMimePart *mime_part;
mime_part = camel_multipart_get_part (mp, 1);
@@ -82,21 +79,21 @@ empe_mp_appledouble_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append_printf (part_id, ".appledouble.1");
- parts = e_mail_parser_parse_part (
- parser, mime_part, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, mime_part, part_id,
+ cancellable, out_mail_parts);
g_string_truncate (part_id, len);
} else {
-
- parts = e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source",
- cancellable);
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
}
}
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-multipart-digest.c b/em-format/e-mail-parser-multipart-digest.c
index 2acd8ee614..70f5eebda0 100644
--- a/em-format/e-mail-parser-multipart-digest.c
+++ b/em-format/e-mail-parser-multipart-digest.c
@@ -56,31 +56,27 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "multipart/digest",
NULL };
-static GSList *
+static gboolean
empe_mp_digest_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMultipart *mp;
gint i, nparts, len;
- GSList *parts;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
- if (!CAMEL_IS_MULTIPART (mp)) {
+ if (!CAMEL_IS_MULTIPART (mp))
return e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source", cancellable);
- }
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
len = part_id->len;
nparts = camel_multipart_get_number (mp);
- parts = NULL;
for (i = 0; i < nparts; i++) {
CamelMimePart *subpart;
CamelContentType *ct;
@@ -99,43 +95,39 @@ empe_mp_digest_parse (EMailParserExtension *extension,
if (ct && !camel_content_type_is (ct, "message", "rfc822")) {
cts = camel_content_type_simple (ct);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, subpart, part_id,
- cts, cancellable));
+ e_mail_parser_parse_part_as (
+ parser, subpart, part_id, cts,
+ cancellable, out_mail_parts);
g_free (cts);
} else {
- GSList *new_parts;
+ GQueue work_queue = G_QUEUE_INIT;
+ EMailPart *mail_part;
+
+ e_mail_parser_parse_part_as (
+ parser, subpart, part_id, "message/rfc822",
+ cancellable, &work_queue);
- new_parts = e_mail_parser_parse_part_as (
- parser, subpart, part_id,
- "message/rfc822", cancellable);
+ mail_part = g_queue_peek_head (&work_queue);
/* Force the message to be collapsable */
- if (new_parts && new_parts->data &&
- !E_MAIL_PART (new_parts->data)->is_attachment) {
- new_parts = e_mail_parser_wrap_as_attachment (
- parser, subpart, new_parts, part_id,
- cancellable);
- }
+ if (mail_part != NULL && !mail_part->is_attachment)
+ e_mail_parser_wrap_as_attachment (
+ parser, subpart, part_id, &work_queue);
+
+ mail_part = g_queue_peek_head (&work_queue);
/* Force the message to be expanded */
- if (new_parts) {
- EMailPart *p = new_parts->data;
- if (p) {
- p->force_inline = TRUE;
- }
- }
-
- parts = g_slist_concat (parts, new_parts);
+ if (mail_part != NULL)
+ mail_part->force_inline = TRUE;
+
+ e_queue_transfer (&work_queue, out_mail_parts);
}
g_string_truncate (part_id, len);
}
- return parts;
+ return TRUE;
}
static guint32
diff --git a/em-format/e-mail-parser-multipart-encrypted.c b/em-format/e-mail-parser-multipart-encrypted.c
index db417fabbf..fedef393ef 100644
--- a/em-format/e-mail-parser-multipart-encrypted.c
+++ b/em-format/e-mail-parser-multipart-encrypted.c
@@ -28,6 +28,7 @@
#include <glib/gi18n-lib.h>
#include <camel/camel.h>
+#include <libedataserver/libedataserver.h>
typedef struct _EMailParserMultipartEncrypted {
GObject parent;
@@ -54,56 +55,50 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "multipart/encrypted", NULL };
-static GSList *
+static gboolean
empe_mp_encrypted_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelCipherContext *context;
const gchar *protocol;
CamelMimePart *opart;
CamelCipherValidity *valid;
CamelMultipartEncrypted *mpe;
+ GQueue work_queue = G_QUEUE_INIT;
+ GList *head, *link;
GError *local_error = NULL;
- GSList *parts;
gint len;
- GSList *iter;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
mpe = (CamelMultipartEncrypted *) camel_medium_get_content ((CamelMedium *) part);
if (!CAMEL_IS_MULTIPART_ENCRYPTED (mpe)) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Could not parse MIME message. "
"Displaying as source."));
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution/source",
- cancellable));
-
- return parts;
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution/source",
+ cancellable, out_mail_parts);
+
+ return TRUE;
}
/* Currently we only handle RFC2015-style PGP encryption. */
protocol = camel_content_type_param (
((CamelDataWrapper *) mpe)->mime_type, "protocol");
if (!protocol || g_ascii_strcasecmp (protocol, "application/pgp-encrypted") != 0) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Unsupported encryption type for multipart/encrypted"));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, "multipart/mixed",
+ cancellable, out_mail_parts);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "multipart/mixed", cancellable));
- return parts;
+ return TRUE;
}
context = camel_gpg_context_new (e_mail_parser_get_session (parser));
@@ -115,40 +110,34 @@ empe_mp_encrypted_parse (EMailParserExtension *extension,
e_mail_part_preserve_charset_in_content_type (part, opart);
if (local_error != NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Could not parse PGP/MIME message: %s"),
local_error->message);
-
- g_error_free (local_error);
-
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "multipart/mixed", cancellable));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, "multipart/mixed",
+ cancellable, out_mail_parts);
g_object_unref (opart);
g_object_unref (context);
+ g_error_free (local_error);
- return parts;
+ return TRUE;
}
len = part_id->len;
g_string_append (part_id, ".encrypted");
- parts = e_mail_parser_parse_part (
- parser, opart, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, opart, part_id, cancellable, &work_queue);
g_string_truncate (part_id, len);
- /* Update validity of all encrypted sub-parts */
- for (iter = parts; iter; iter = iter->next) {
- EMailPart *mail_part;
+ head = g_queue_peek_head_link (&work_queue);
- mail_part = iter->data;
- if (!mail_part)
- continue;
+ /* Update validity of all encrypted sub-parts */
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
e_mail_part_update_validity (
mail_part, valid,
@@ -156,28 +145,30 @@ empe_mp_encrypted_parse (EMailParserExtension *extension,
E_MAIL_PART_VALIDITY_PGP);
}
+ e_queue_transfer (&work_queue, out_mail_parts);
+
/* Add a widget with details about the encryption, but only when
* the decrypted part isn't itself secured, in that case it has
* created the button itself. */
if (!e_mail_part_is_secured (opart)) {
- GSList *button;
EMailPart *mail_part;
+
g_string_append (part_id, ".encrypted.button");
- button = e_mail_parser_parse_part_as (
+ e_mail_parser_parse_part_as (
parser, part, part_id,
"application/vnd.evolution.widget.secure-button",
- cancellable);
- if (button && button->data) {
- mail_part = button->data;
+ cancellable, &work_queue);
+
+ mail_part = g_queue_peek_head (&work_queue);
+ if (mail_part != NULL)
e_mail_part_update_validity (
mail_part, valid,
E_MAIL_PART_VALIDITY_ENCRYPTED |
E_MAIL_PART_VALIDITY_PGP);
- }
- parts = g_slist_concat (parts, button);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, len);
}
@@ -188,7 +179,7 @@ empe_mp_encrypted_parse (EMailParserExtension *extension,
g_object_unref (opart);
g_object_unref (context);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-multipart-mixed.c b/em-format/e-mail-parser-multipart-mixed.c
index 69882739d9..f416ffda24 100644
--- a/em-format/e-mail-parser-multipart-mixed.c
+++ b/em-format/e-mail-parser-multipart-mixed.c
@@ -59,79 +59,73 @@ static const gchar * parser_mime_types[] = { "multipart/mixed",
"multipart/*",
NULL };
-static GSList *
+static gboolean
empe_mp_mixed_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMultipart *mp;
gint i, nparts, len;
- GSList *parts;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
- if (!CAMEL_IS_MULTIPART (mp)) {
- parts = e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source", cancellable);
- return parts;
- }
+ if (!CAMEL_IS_MULTIPART (mp))
+ return e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
len = part_id->len;
- parts = NULL;
nparts = camel_multipart_get_number (mp);
for (i = 0; i < nparts; i++) {
+ GQueue work_queue = G_QUEUE_INIT;
+ EMailPart *mail_part;
CamelMimePart *subpart;
CamelContentType *ct;
- GSList *new_parts;
subpart = camel_multipart_get_part (mp, i);
g_string_append_printf (part_id, ".mixed.%d", i);
- new_parts = e_mail_parser_parse_part (
- parser, subpart, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, subpart, part_id, cancellable, &work_queue);
+
+ mail_part = g_queue_peek_head (&work_queue);
ct = camel_mime_part_get_content_type (subpart);
- /* Display parts with CID as attachments (unless they already are
- * attachments) */
- if (new_parts && new_parts->data &&
- (E_MAIL_PART (new_parts->data)->cid != NULL) &&
- !E_MAIL_PART (new_parts->data)->is_attachment) {
+ /* Display parts with CID as attachments
+ * (unless they already are attachments). */
+ if (mail_part != NULL &&
+ mail_part->cid != NULL &&
+ !mail_part->is_attachment) {
- parts = g_slist_concat (
- parts,
- e_mail_parser_wrap_as_attachment (
- parser, subpart, new_parts,
- part_id, cancellable));
+ e_mail_parser_wrap_as_attachment (
+ parser, subpart, part_id, &work_queue);
/* Force messages to be expandable */
- } else if (!new_parts ||
+ } else if (mail_part == NULL ||
(camel_content_type_is (ct, "message", "rfc822") &&
- new_parts && new_parts->data &&
- !E_MAIL_PART (new_parts->data)->is_attachment)) {
-
- parts = g_slist_concat (
- parts,
- e_mail_parser_wrap_as_attachment (
- parser, subpart, new_parts,
- part_id, cancellable));
- if (parts && parts->data)
- E_MAIL_PART (parts->data)->force_inline = TRUE;
- } else {
- parts = g_slist_concat (parts, new_parts);
+ mail_part != NULL && !mail_part->is_attachment)) {
+
+ e_mail_parser_wrap_as_attachment (
+ parser, subpart, part_id, &work_queue);
+
+ mail_part = g_queue_peek_head (&work_queue);
+
+ if (mail_part != NULL)
+ mail_part->force_inline = TRUE;
}
+ e_queue_transfer (&work_queue, out_mail_parts);
+
g_string_truncate (part_id, len);
}
- return parts;
+ return TRUE;
}
static guint32
diff --git a/em-format/e-mail-parser-multipart-related.c b/em-format/e-mail-parser-multipart-related.c
index e72b61e26c..0a368ea0c8 100644
--- a/em-format/e-mail-parser-multipart-related.c
+++ b/em-format/e-mail-parser-multipart-related.c
@@ -57,79 +57,75 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar * parser_mime_types[] = { "multipart/related",
NULL };
-static GSList *
+static gboolean
empe_mp_related_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMultipart *mp;
CamelMimePart *body_part, *display_part = NULL;
gint i, nparts, partidlen, displayid = 0;
- GSList *parts;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
- if (!CAMEL_IS_MULTIPART (mp)) {
+ if (!CAMEL_IS_MULTIPART (mp))
return e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source", cancellable);
- }
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
display_part = e_mail_part_get_related_display_part (part, &displayid);
- if (display_part == NULL) {
+ if (display_part == NULL)
return e_mail_parser_parse_part_as (
- parser, part, part_id, "multipart/mixed",
- cancellable);
- }
+ parser, part, part_id, "multipart/mixed",
+ cancellable, out_mail_parts);
/* The to-be-displayed part goes first */
partidlen = part_id->len;
g_string_append_printf (part_id, ".related.%d", displayid);
- parts = e_mail_parser_parse_part (
- parser, display_part, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, display_part, part_id, cancellable, out_mail_parts);
g_string_truncate (part_id, partidlen);
/* Process the related parts */
nparts = camel_multipart_get_number (mp);
for (i = 0; i < nparts; i++) {
- GSList *list, *iter;
+ GQueue work_queue = G_QUEUE_INIT;
+ GList *head, *link;
+
body_part = camel_multipart_get_part (mp, i);
- list = NULL;
if (body_part == display_part)
continue;
g_string_append_printf (part_id, ".related.%d", i);
- list = e_mail_parser_parse_part (
- parser, body_part, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, body_part, part_id,
+ cancellable, &work_queue);
g_string_truncate (part_id, partidlen);
- for (iter = list; iter; iter = iter->next) {
- EMailPart *mail_part;
+ head = g_queue_peek_head_link (&work_queue);
- mail_part = iter->data;
- if (!mail_part)
- continue;
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
/* Don't render the part on it's own! */
if (mail_part->cid != NULL)
mail_part->is_hidden = TRUE;
}
- parts = g_slist_concat (parts, list);
+ e_queue_transfer (&work_queue, out_mail_parts);
}
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-multipart-signed.c b/em-format/e-mail-parser-multipart-signed.c
index b7d395ab05..60fac35c7f 100644
--- a/em-format/e-mail-parser-multipart-signed.c
+++ b/em-format/e-mail-parser-multipart-signed.c
@@ -28,6 +28,7 @@
#include <glib/gi18n-lib.h>
#include <camel/camel.h>
+#include <libedataserver/libedataserver.h>
typedef struct _EMailParserMultipartSigned {
GObject parent;
@@ -56,33 +57,30 @@ static const gchar * parser_mime_types[] = { "multipart/signed",
"application/pgp-signature",
NULL };
-static GSList *
+static gboolean
empe_mp_signed_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelMimePart *cpart;
CamelMultipartSigned *mps;
CamelCipherContext *cipher = NULL;
CamelSession *session;
guint32 validity_type;
- GSList *parts;
CamelCipherValidity *valid;
GError *local_error = NULL;
gint i, nparts, len;
gboolean secured;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
/* If the part is application/pgp-signature sub-part then skip it. */
if (!CAMEL_IS_MULTIPART (part)) {
CamelContentType *ct;
ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (part));
if (camel_content_type_is (ct, "application", "pgp-signature")) {
- return g_slist_alloc ();
+ return TRUE;
}
}
@@ -92,18 +90,16 @@ empe_mp_signed_parse (EMailParserExtension *extension,
cpart = camel_multipart_get_part (
(CamelMultipart *) mps,
CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Could not parse MIME message. "
"Displaying as source."));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.source",
- cancellable));
- return parts;
+ return TRUE;
}
session = e_mail_parser_get_session (parser);
@@ -127,95 +123,89 @@ empe_mp_signed_parse (EMailParserExtension *extension,
}
if (cipher == NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Unsupported signature format"));
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, "multipart/mixed",
+ cancellable, out_mail_parts);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "multipart/mixed", cancellable));
-
- return parts;
+ return TRUE;
}
valid = camel_cipher_context_verify_sync (
cipher, part, cancellable, &local_error);
if (local_error != NULL) {
- parts = e_mail_parser_error (
- parser, cancellable,
+ e_mail_parser_error (
+ parser, out_mail_parts,
_("Error verifying signature: %s"),
local_error->message);
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, "multipart/mixed",
+ cancellable, out_mail_parts);
+ g_object_unref (cipher);
g_error_free (local_error);
- parts = g_slist_concat (
- parts,
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "multipart/mixed", cancellable));
-
- g_object_unref (cipher);
- return parts;
+ return TRUE;
}
nparts = camel_multipart_get_number (CAMEL_MULTIPART (mps));
secured = FALSE;
len = part_id->len;
- parts = NULL;
for (i = 0; i < nparts; i++) {
+ GQueue work_queue = G_QUEUE_INIT;
+ GList *head, *link;
CamelMimePart *subpart;
- GSList *mail_parts, *iter;
+
subpart = camel_multipart_get_part (CAMEL_MULTIPART (mps), i);
g_string_append_printf (part_id, ".signed.%d", i);
- mail_parts = e_mail_parser_parse_part (
- parser, subpart, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, subpart, part_id, cancellable, &work_queue);
g_string_truncate (part_id, len);
if (!secured)
secured = e_mail_part_is_secured (subpart);
- for (iter = mail_parts; iter; iter = iter->next) {
- EMailPart *mail_part;
+ head = g_queue_peek_head_link (&work_queue);
- mail_part = iter->data;
- if (!mail_part)
- continue;
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
e_mail_part_update_validity (
mail_part, valid,
validity_type | E_MAIL_PART_VALIDITY_SIGNED);
}
- parts = g_slist_concat (parts, mail_parts);
+ e_queue_transfer (&work_queue, out_mail_parts);
}
/* Add a widget with details about the encryption, but only when
- * the encrypted isn't itself secured, in that case it has created
- * the button itself */
+ * the encrypted isn't itself secured, in that case it has created
+ * the button itself. */
if (!secured) {
- GSList *button;
+ GQueue work_queue = G_QUEUE_INIT;
EMailPart *mail_part;
+
g_string_append (part_id, ".signed.button");
- button = e_mail_parser_parse_part_as (
+ e_mail_parser_parse_part_as (
parser, part, part_id,
"application/vnd.evolution.widget.secure-button",
- cancellable);
- if (button && button->data) {
- mail_part = button->data;
+ cancellable, &work_queue);
+ mail_part = g_queue_peek_head (&work_queue);
+
+ if (mail_part != NULL)
e_mail_part_update_validity (
mail_part, valid,
validity_type | E_MAIL_PART_VALIDITY_SIGNED);
- }
- parts = g_slist_concat (parts, button);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, len);
}
@@ -224,7 +214,7 @@ empe_mp_signed_parse (EMailParserExtension *extension,
g_object_unref (cipher);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-secure-button.c b/em-format/e-mail-parser-secure-button.c
index 92a0f61958..cb4282cef0 100644
--- a/em-format/e-mail-parser-secure-button.c
+++ b/em-format/e-mail-parser-secure-button.c
@@ -54,12 +54,13 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar *parser_mime_types[] = { "application/vnd.evolution.widget.secure-button", NULL };
-static GSList *
+static gboolean
empe_secure_button_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailPart *mail_part;
gint len;
@@ -70,7 +71,9 @@ empe_secure_button_parse (EMailParserExtension *extension,
mail_part->mime_type = g_strdup ("application/vnd.evolution.widget.secure-button");
g_string_truncate (part_id, len);
- return g_slist_append (NULL, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
+
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-source.c b/em-format/e-mail-parser-source.c
index db08144fa2..ee563acf9f 100644
--- a/em-format/e-mail-parser-source.c
+++ b/em-format/e-mail-parser-source.c
@@ -54,19 +54,17 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar *parser_mime_types[] = { "application/vnd.evolution.source", NULL };
-static GSList *
+static gboolean
empe_source_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailPart *mail_part;
gint len;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
len = part_id->len;
g_string_append (part_id, ".source");
@@ -74,7 +72,9 @@ empe_source_parse (EMailParserExtension *extension,
mail_part->mime_type = g_strdup ("application/vnd.evolution.source");
g_string_truncate (part_id, len);
- return g_slist_append (NULL, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
+
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-text-enriched.c b/em-format/e-mail-parser-text-enriched.c
index c23130763c..34a64c38f0 100644
--- a/em-format/e-mail-parser-text-enriched.c
+++ b/em-format/e-mail-parser-text-enriched.c
@@ -57,21 +57,20 @@ static const gchar *parser_mime_types[] = { "text/richtext",
"text/enriched",
NULL };
-static GSList *
+static gboolean
empe_text_enriched_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
+ GQueue work_queue = G_QUEUE_INIT;
EMailPart *mail_part;
const gchar *tmp;
gint len;
CamelContentType *ct;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
len = part_id->len;
g_string_append (part_id, ".text_enriched");
@@ -88,13 +87,15 @@ empe_text_enriched_parse (EMailParserExtension *extension,
g_string_truncate (part_id, len);
- if (e_mail_part_is_attachment (part)) {
- return e_mail_parser_wrap_as_attachment (
- parser, part, g_slist_append (NULL, mail_part),
- part_id, cancellable);
- }
+ g_queue_push_tail (&work_queue, mail_part);
+
+ if (e_mail_part_is_attachment (part))
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
- return g_slist_append (NULL, mail_part);
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-text-html.c b/em-format/e-mail-parser-text-html.c
index b824931e09..a28a8ff5f0 100644
--- a/em-format/e-mail-parser-text-html.c
+++ b/em-format/e-mail-parser-text-html.c
@@ -57,22 +57,21 @@ G_DEFINE_TYPE_EXTENDED (
static const gchar *parser_mime_types[] = { "text/html", NULL };
-static GSList *
+static gboolean
empe_text_html_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
- EMailPart *empart;
+ GQueue work_queue = G_QUEUE_INIT;
+ EMailPart *mail_part;
const gchar *location;
gchar *cid = NULL;
const gchar *base;
gint len;
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
-
cid = NULL;
base = camel_medium_get_header (CAMEL_MEDIUM (part), "content-base");
location = camel_mime_part_get_content_location (part);
@@ -93,18 +92,20 @@ empe_text_html_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append (part_id, ".text_html");
- empart = e_mail_part_new (part, part_id->str);
- empart->mime_type = g_strdup ("text/html");
- empart->cid = cid;
+ mail_part = e_mail_part_new (part, part_id->str);
+ mail_part->mime_type = g_strdup ("text/html");
+ mail_part->cid = cid;
g_string_truncate (part_id, len);
- if (e_mail_part_is_attachment (part)) {
- return e_mail_parser_wrap_as_attachment (
- parser, part, g_slist_append (NULL, empart),
- part_id, cancellable);
- }
+ g_queue_push_head (&work_queue, mail_part);
+
+ if (e_mail_part_is_attachment (part))
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
- return g_slist_append (NULL, empart);
+ return TRUE;
}
static const gchar **
diff --git a/em-format/e-mail-parser-text-plain.c b/em-format/e-mail-parser-text-plain.c
index bdfcd15e5d..4c9c0b36a5 100644
--- a/em-format/e-mail-parser-text-plain.c
+++ b/em-format/e-mail-parser-text-plain.c
@@ -80,32 +80,30 @@ part_is_empty (CamelMimePart *part)
return TRUE;
}
-static GSList *
+static gboolean
process_part (EMailParser *parser,
GString *part_id,
gint part_number,
CamelMimePart *part,
gboolean is_attachment,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelContentType *type;
EMailPart *empart;
gint s_len = part_id->len;
- GSList *parts;
- if (part_is_empty (part)) {
- return g_slist_alloc ();
- }
+ if (part_is_empty (part))
+ return TRUE;
type = camel_mime_part_get_content_type (part);
if (!camel_content_type_is (type, "text", "*")) {
-
- parts = e_mail_parser_parse_part (
- parser, CAMEL_MIME_PART (part),
- part_id, cancellable);
- return parts;
+ e_mail_parser_parse_part (
+ parser, CAMEL_MIME_PART (part), part_id,
+ cancellable, out_mail_parts);
} else if (!camel_content_type_is (type, "text", "calendar")) {
+ GQueue work_queue = G_QUEUE_INIT;
g_string_append_printf (part_id, ".plain_text.%d", part_number);
@@ -114,37 +112,35 @@ process_part (EMailParser *parser,
g_string_truncate (part_id, s_len);
- if (is_attachment) {
-
- return e_mail_parser_wrap_as_attachment (
- parser, part,
- g_slist_append (NULL, empart),
- part_id, cancellable);
+ g_queue_push_tail (&work_queue, empart);
- }
+ if (is_attachment)
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
- return g_slist_append (NULL, empart);
- }
+ e_queue_transfer (&work_queue, out_mail_parts);
- g_string_append_printf (part_id, ".inline.%d", part_number);
+ } else {
+ g_string_append_printf (part_id, ".inline.%d", part_number);
- parts = e_mail_parser_parse_part (
- parser, CAMEL_MIME_PART (part),
- part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, CAMEL_MIME_PART (part), part_id,
+ cancellable, out_mail_parts);
- g_string_truncate (part_id, s_len);
+ g_string_truncate (part_id, s_len);
+ }
- return parts;
+ return TRUE;
}
-static GSList *
+static gboolean
empe_text_plain_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
- GSList *parts;
CamelStream *filtered_stream, *null;
CamelMultipart *mp;
CamelDataWrapper *dw;
@@ -154,13 +150,11 @@ empe_text_plain_parse (EMailParserExtension *extension,
gboolean charset_added = FALSE;
const gchar *snoop_type = NULL;
gboolean is_attachment;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
+ gint n_parts_added = 0;
dw = camel_medium_get_content ((CamelMedium *) part);
if (!dw)
- return NULL;
+ return FALSE;
/* This scans the text part for inline-encoded data, creates
* a multipart of all the parts inside it. */
@@ -206,7 +200,7 @@ empe_text_plain_parse (EMailParserExtension *extension,
return process_part (
parser, part_id, 0,
part, e_mail_part_is_attachment (part),
- cancellable);
+ cancellable, out_mail_parts);
}
mp = e_mail_inline_filter_get_multipart (inline_filter);
@@ -220,7 +214,6 @@ empe_text_plain_parse (EMailParserExtension *extension,
/* We handle our made-up multipart here, so we don't recursively call ourselves */
count = camel_multipart_get_number (mp);
- parts = NULL;
is_attachment = ((count == 1) && (e_mail_part_is_attachment (part)));
@@ -230,17 +223,15 @@ empe_text_plain_parse (EMailParserExtension *extension,
if (!newpart)
continue;
- parts = g_slist_concat (
- parts,
- process_part (
- parser, part_id, i,
- newpart, is_attachment,
- cancellable));
+ n_parts_added += process_part (
+ parser, part_id, i,
+ newpart, is_attachment,
+ cancellable, out_mail_parts);
}
g_object_unref (mp);
- return parts;
+ return n_parts_added;
}
static const gchar **
diff --git a/em-format/e-mail-parser.c b/em-format/e-mail-parser.c
index 8e5ccd4ef8..55e6eef47f 100644
--- a/em-format/e-mail-parser.c
+++ b/em-format/e-mail-parser.c
@@ -62,11 +62,11 @@ mail_parser_run (EMailParser *parser,
{
EMailExtensionRegistry *reg;
CamelMimeMessage *message;
- EMailPart *part;
+ EMailPart *mail_part;
GQueue *parsers;
+ GQueue mail_part_queue = G_QUEUE_INIT;
GList *iter;
GString *part_id;
- GSList *list_of_parts;
message = e_mail_part_list_get_message (part_list);
@@ -79,18 +79,19 @@ mail_parser_run (EMailParser *parser,
parsers = e_mail_extension_registry_get_for_mime_type (
reg, "message/*");
- /* parsers == NULL means, that the internal Evolution parser
- * extensions were not loaded. Something is terribly wrong. */
+ /* No parsers means the internal Evolution parser
+ * extensions were not loaded. Something is terribly wrong! */
g_return_if_fail (parsers != NULL);
part_id = g_string_new (".message");
- part = e_mail_part_new (CAMEL_MIME_PART (message), ".message");
- e_mail_part_list_add_part (part_list, part);
- e_mail_part_unref (part);
+ mail_part = e_mail_part_new (CAMEL_MIME_PART (message), ".message");
+ e_mail_part_list_add_part (part_list, mail_part);
+ e_mail_part_unref (mail_part);
for (iter = parsers->head; iter; iter = iter->next) {
EMailParserExtension *extension;
+ gboolean message_handled;
if (g_cancellable_is_cancelled (cancellable))
break;
@@ -99,24 +100,19 @@ mail_parser_run (EMailParser *parser,
if (!extension)
continue;
- list_of_parts = e_mail_parser_extension_parse (
+ message_handled = e_mail_parser_extension_parse (
extension, parser,
CAMEL_MIME_PART (message),
- part_id, cancellable);
+ part_id, cancellable, &mail_part_queue);
- if (list_of_parts != NULL)
+ if (message_handled)
break;
}
- while (list_of_parts != NULL) {
- part = list_of_parts->data;
- if (part != NULL) {
- e_mail_part_list_add_part (part_list, part);
- e_mail_part_unref (part);
- }
-
- list_of_parts = g_slist_delete_link (
- list_of_parts, list_of_parts);
+ while (!g_queue_is_empty (&mail_part_queue)) {
+ mail_part = g_queue_pop_head (&mail_part_queue);
+ e_mail_part_list_add_part (part_list, mail_part);
+ e_mail_part_unref (mail_part);
}
g_string_free (part_id, TRUE);
@@ -428,15 +424,16 @@ e_mail_parser_parse_finish (EMailParser *parser,
return g_object_ref (part_list);
}
-GSList *
+gboolean
e_mail_parser_parse_part (EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
CamelContentType *ct;
gchar *mime_type;
- GSList *list;
+ gint n_parts_queued = 0;
ct = camel_mime_part_get_content_type (part);
if (!ct) {
@@ -448,32 +445,31 @@ e_mail_parser_parse_part (EMailParser *parser,
g_free (tmp);
}
- list = e_mail_parser_parse_part_as (
- parser, part, part_id, mime_type, cancellable);
+ n_parts_queued = e_mail_parser_parse_part_as (
+ parser, part, part_id, mime_type,
+ cancellable, out_mail_parts);
if (ct) {
g_free (mime_type);
}
- return list;
+ return n_parts_queued;
}
-GSList *
+gboolean
e_mail_parser_parse_part_as (EMailParser *parser,
CamelMimePart *part,
GString *part_id,
const gchar *mime_type,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
GQueue *parsers;
GList *iter;
EMailExtensionRegistry *reg;
EMailParserClass *parser_class;
- GSList *part_list = NULL;
gchar *as_mime_type;
-
- if (g_cancellable_is_cancelled (cancellable))
- return NULL;
+ gboolean mime_part_handled = FALSE;
if (mime_type)
as_mime_type = g_ascii_strdown (mime_type, -1);
@@ -491,9 +487,10 @@ e_mail_parser_parse_part_as (EMailParser *parser,
if (as_mime_type)
g_free (as_mime_type);
- if (!parsers) {
- return e_mail_parser_wrap_as_attachment (
- parser, part, NULL, part_id, cancellable);
+ if (parsers == NULL) {
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, out_mail_parts);
+ return TRUE;
}
for (iter = parsers->head; iter; iter = iter->next) {
@@ -503,19 +500,20 @@ e_mail_parser_parse_part_as (EMailParser *parser,
if (!extension)
continue;
- part_list = e_mail_parser_extension_parse (
- extension, parser, part, part_id, cancellable);
+ mime_part_handled = e_mail_parser_extension_parse (
+ extension, parser, part, part_id,
+ cancellable, out_mail_parts);
- if (part_list)
+ if (mime_part_handled)
break;
}
- return part_list;
+ return mime_part_handled;
}
-GSList *
+void
e_mail_parser_error (EMailParser *parser,
- GCancellable *cancellable,
+ GQueue *out_mail_parts,
const gchar *format,
...)
{
@@ -525,8 +523,9 @@ e_mail_parser_error (EMailParser *parser,
gchar *uri;
va_list ap;
- g_return_val_if_fail (E_IS_MAIL_PARSER (parser), NULL);
- g_return_val_if_fail (format != NULL, NULL);
+ g_return_if_fail (E_IS_MAIL_PARSER (parser));
+ g_return_if_fail (out_mail_parts != NULL);
+ g_return_if_fail (format != NULL);
va_start (ap, format);
errmsg = g_strdup_vprintf (format, ap);
@@ -551,7 +550,7 @@ e_mail_parser_error (EMailParser *parser,
g_free (uri);
g_object_unref (part);
- return g_slist_append (NULL, mail_part);
+ g_queue_push_tail (out_mail_parts, mail_part);
}
static void
@@ -581,14 +580,14 @@ load_attachment_idle (EAttachment *attachment)
return FALSE;
}
-GSList *
+void
e_mail_parser_wrap_as_attachment (EMailParser *parser,
CamelMimePart *part,
- GSList *parts,
GString *part_id,
- GCancellable *cancellable)
+ GQueue *parts_queue)
{
EMailPartAttachment *empa;
+ EMailPart *first_part;
const gchar *snoop_mime_type, *cid;
GQueue *extensions;
CamelContentType *ct;
@@ -644,7 +643,12 @@ e_mail_parser_wrap_as_attachment (EMailParser *parser,
e_mail_part_is_inline (part, extensions));
empa->snoop_mime_type = snoop_mime_type;
empa->attachment = e_attachment_new ();
- empa->attachment_view_part_id = parts ? g_strdup (E_MAIL_PART (parts->data)->id) : NULL;
+
+ first_part = g_queue_peek_head (parts_queue);
+ if (first_part != NULL) {
+ empa->attachment_view_part_id = g_strdup (first_part->id);
+ first_part->is_hidden = TRUE;
+ }
cid = camel_mime_part_get_content_id (part);
if (cid)
@@ -692,13 +696,10 @@ e_mail_parser_wrap_as_attachment (EMailParser *parser,
g_object_unref (fileinfo);
}
- if (parts && parts->data) {
- E_MAIL_PART (parts->data)->is_hidden = TRUE;
- }
-
g_string_truncate (part_id, part_id_len);
- return g_slist_prepend (parts, empa);
+ /* Push to head, not tail. */
+ g_queue_push_head (parts_queue, empa);
}
CamelSession *
diff --git a/em-format/e-mail-parser.h b/em-format/e-mail-parser.h
index 202e28d267..77818b86e6 100644
--- a/em-format/e-mail-parser.h
+++ b/em-format/e-mail-parser.h
@@ -80,28 +80,29 @@ EMailPartList * e_mail_parser_parse_finish (EMailParser *parser,
GAsyncResult *result,
GError **error);
-GSList * e_mail_parser_parse_part (EMailParser *parser,
+gboolean e_mail_parser_parse_part (EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable);
+ GCancellable *cancellable,
+ GQueue *out_mail_parts);
-GSList * e_mail_parser_parse_part_as (EMailParser *parser,
+gboolean e_mail_parser_parse_part_as (EMailParser *parser,
CamelMimePart *part,
GString *part_id,
const gchar *mime_type,
- GCancellable *cancellable);
-
-GSList * e_mail_parser_error (EMailParser *parser,
GCancellable *cancellable,
+ GQueue *out_mail_parts);
+
+void e_mail_parser_error (EMailParser *parser,
+ GQueue *out_mail_parts,
const gchar *format,
...) G_GNUC_PRINTF (3, 4);
-GSList * e_mail_parser_wrap_as_attachment
+void e_mail_parser_wrap_as_attachment
(EMailParser *parser,
CamelMimePart *part,
- GSList *parts,
GString *part_id,
- GCancellable *cancellable);
+ GQueue *parts_queue);
CamelSession * e_mail_parser_get_session (EMailParser *parser);