aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2012-12-06 08:42:15 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-12-08 03:01:04 +0800
commit3924dc759dbf38df0f9ff6941990dcf242478617 (patch)
treeaa00cb03ef21e3b11759dd9f094c9c2563d05956
parent4611bcd7b8958c5ffadccc8b68989c839cf3f144 (diff)
downloadgsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.tar
gsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.tar.gz
gsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.tar.bz2
gsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.tar.lz
gsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.tar.xz
gsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.tar.zst
gsoc2013-evolution-3924dc759dbf38df0f9ff6941990dcf242478617.zip
EMailParserExtension: Collect EMailParts in a GQueue.
Collect EMailParts in a GQueue provided to the EMailParserExtension, and change the return type of parse() to gboolean to indicate whether the given CamelMimePart was handled (even if no parts were added to the output GQueue). This avoids the awkward corner case of a parser extension returning a linked list node with a NULL data member to indicate the CamelMimePart was handled but no EMailParts produced, and then having to watch out for that NULL data member corner case throughout the application. Also, remove the GCancellable parameter from e_mail_parser_error() and e_mail_parser_wrap_as_attachment() since neither function blocks.
-rw-r--r--composer/e-msg-composer.c15
-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
-rw-r--r--modules/audio-inline/e-mail-parser-audio-inline.c25
-rw-r--r--modules/itip-formatter/e-mail-parser-itip.c17
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.c179
-rw-r--r--modules/text-highlight/e-mail-parser-text-highlight.c26
-rw-r--r--modules/tnef-attachment/e-mail-parser-tnef-attachment.c34
-rw-r--r--modules/vcard-inline/e-mail-parser-vcard-inline.c29
34 files changed, 725 insertions, 749 deletions
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 4fa48a717b..5cd9a70f75 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -194,7 +194,7 @@ emcu_part_to_html (CamelSession *session,
GString *part_id;
EShell *shell;
GtkWindow *window;
- GSList *list;
+ GQueue queue = G_QUEUE_INIT;
shell = e_shell_get_default ();
window = e_shell_get_active_window (shell);
@@ -207,13 +207,12 @@ emcu_part_to_html (CamelSession *session,
part_id = g_string_sized_new (0);
parser = e_mail_parser_new (session);
- list = e_mail_parser_parse_part (parser, part, part_id, cancellable);
- while (list != NULL) {
- if (list->data != NULL) {
- e_mail_part_list_add_part (part_list, list->data);
- e_mail_part_unref (list->data);
- }
- list = g_slist_delete_link (list, list);
+ e_mail_parser_parse_part (
+ parser, part, part_id, cancellable, &queue);
+ while (!g_queue_is_empty (&queue)) {
+ EMailPart *mail_part = g_queue_pop_head (&queue);
+ e_mail_part_list_add_part (part_list, mail_part);
+ e_mail_part_unref (mail_part);
}
g_string_free (part_id, TRUE);
g_object_unref (parser);
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);
diff --git a/modules/audio-inline/e-mail-parser-audio-inline.c b/modules/audio-inline/e-mail-parser-audio-inline.c
index 5509306118..ca87693fe4 100644
--- a/modules/audio-inline/e-mail-parser-audio-inline.c
+++ b/modules/audio-inline/e-mail-parser-audio-inline.c
@@ -101,15 +101,18 @@ mail_part_audio_inline_free (EMailPart *mail_part)
}
}
-static GSList *
+static gint
empe_audio_inline_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_queue)
{
EMailPartAudioInline *mail_part;
+ GQueue work_queue = G_QUEUE_INIT;
gint len;
+ gint n_parts_added = 0;
len = part_id->len;
g_string_append (part_id, ".org-gnome-audio-inline-button-panel");
@@ -117,16 +120,22 @@ empe_audio_inline_parse (EMailParserExtension *extension,
d (printf ("audio inline formatter: format classid %s\n", part_id->str));
mail_part = (EMailPartAudioInline *) e_mail_part_subclass_new (
- part, part_id->str, sizeof (EMailPartAudioInline),
- (GFreeFunc) mail_part_audio_inline_free);
+ part, part_id->str, sizeof (EMailPartAudioInline),
+ (GFreeFunc) mail_part_audio_inline_free);
mail_part->parent.mime_type = camel_content_type_simple (
- camel_mime_part_get_content_type (part));
+ camel_mime_part_get_content_type (part));
mail_part->parent.is_attachment = TRUE;
g_string_truncate (part_id, len);
- 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);
+ n_parts_added++;
+
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_queue);
+
+ return TRUE;
}
static guint32
diff --git a/modules/itip-formatter/e-mail-parser-itip.c b/modules/itip-formatter/e-mail-parser-itip.c
index 56bbd53da1..505842807a 100644
--- a/modules/itip-formatter/e-mail-parser-itip.c
+++ b/modules/itip-formatter/e-mail-parser-itip.c
@@ -180,12 +180,13 @@ bind_itip_view (EMailPart *part,
/*******************************************************************************/
-static GSList *
+static gboolean
empe_itip_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EShell *shell;
GSettings *settings;
@@ -195,7 +196,7 @@ empe_itip_parse (EMailParserExtension *extension,
GByteArray *byte_array;
gint len;
const CamelContentDisposition *disposition;
- GSList *parts;
+ GQueue work_queue = G_QUEUE_INIT;
len = part_id->len;
g_string_append_printf (part_id, ".itip");
@@ -234,18 +235,20 @@ empe_itip_parse (EMailParserExtension *extension,
g_object_unref (stream);
- parts = g_slist_append (NULL, itip_part);
+ g_queue_push_tail (&work_queue, itip_part);
disposition = camel_mime_part_get_content_disposition (part);
if (disposition &&
(g_strcmp0 (disposition->disposition, "attachment") == 0)) {
- parts = e_mail_parser_wrap_as_attachment (
- parser, part, parts, part_id, cancellable);
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
}
+ e_queue_transfer (&work_queue, out_mail_parts);
+
g_string_truncate (part_id, len);
- return parts;
+ return TRUE;
}
static guint32
diff --git a/modules/prefer-plain/e-mail-parser-prefer-plain.c b/modules/prefer-plain/e-mail-parser-prefer-plain.c
index 66ff32106c..296369ed32 100644
--- a/modules/prefer-plain/e-mail-parser-prefer-plain.c
+++ b/modules/prefer-plain/e-mail-parser-prefer-plain.c
@@ -99,18 +99,19 @@ enum {
PROP_SHOW_SUPPRESSED
};
-static GSList *
+static void
make_part_attachment (EMailParser *parser,
CamelMimePart *part,
GString *part_id,
gboolean force_html,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
- GSList *parts;
-
if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
+ GQueue work_queue = G_QUEUE_INIT;
EMailPart *mail_part;
gint len;
+
/* always show HTML as attachments and not inline */
camel_mime_part_set_disposition (part, "attachment");
@@ -126,9 +127,12 @@ make_part_attachment (EMailParser *parser,
mail_part->mime_type = g_strdup ("text/html");
g_string_truncate (part_id, len);
- parts = 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);
+
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
} else if (force_html && CAMEL_IS_MIME_MESSAGE (part)) {
/* message was asked to be formatted as text/html;
@@ -137,52 +141,51 @@ make_part_attachment (EMailParser *parser,
CamelDataWrapper *content;
content = camel_medium_get_content (CAMEL_MEDIUM (part));
- g_return_val_if_fail (content != NULL, NULL);
+ g_return_if_fail (content != NULL);
new_part = camel_mime_part_new ();
camel_medium_set_content (CAMEL_MEDIUM (new_part), content);
- parts = e_mail_parser_parse_part (
- parser, new_part, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, new_part, part_id,
+ cancellable, out_mail_parts);
g_object_unref (new_part);
} else {
- parts = e_mail_parser_parse_part (
- parser, part, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, part, part_id, cancellable, out_mail_parts);
}
-
- return parts;
}
static void
-hide_parts (GSList *parts)
+hide_parts (GQueue *work_queue)
{
- GSList *iter;
+ GList *head, *link;
- for (iter = parts; iter; iter = g_slist_next (iter)) {
- EMailPart *p = iter->data;
+ head = g_queue_peek_head_link (work_queue);
- if (!p)
- continue;
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
- p->is_hidden = TRUE;
+ mail_part->is_hidden = TRUE;
}
}
-static GSList *
+static gboolean
empe_prefer_plain_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailParserPreferPlain *emp_pp;
CamelMultipart *mp;
gint i, nparts, partidlen;
- GSList *parts;
CamelContentType *ct;
gboolean has_calendar = FALSE;
- GSList *plain_text_parts = NULL;
+ GQueue plain_text_parts = G_QUEUE_INIT;
+ GQueue work_queue = G_QUEUE_INIT;
emp_pp = (EMailParserPreferPlain *) extension;
@@ -194,36 +197,35 @@ empe_prefer_plain_parse (EMailParserExtension *extension,
/* Prevent recursion, fall back to next (real text/html) parser */
if (strstr (part_id->str, ".alternative-prefer-plain.") != NULL)
- return NULL;
+ return FALSE;
/* Not enforcing text/plain, so use real parser */
if (emp_pp->mode != ONLY_PLAIN)
- return NULL;
+ return FALSE;
/* Enforcing text/plain, but got only HTML part, so add it
* as attachment, to not show empty message preview, which
* is confusing. */
- return make_part_attachment (
- parser, part, part_id,
- FALSE, cancellable);
+ make_part_attachment (
+ parser, part, part_id, FALSE,
+ cancellable, out_mail_parts);
+
+ return TRUE;
}
- parts = NULL;
partidlen = part_id->len;
mp = (CamelMultipart *) camel_medium_get_content (CAMEL_MEDIUM (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);
- }
+ "application/vnd.evolution.source",
+ cancellable, out_mail_parts);
nparts = camel_multipart_get_number (mp);
for (i = 0; i < nparts; i++) {
-
CamelMimePart *sp;
- GSList *sparts = NULL;
sp = camel_multipart_get_part (mp, i);
ct = camel_mime_part_get_content_type (sp);
@@ -232,61 +234,52 @@ empe_prefer_plain_parse (EMailParserExtension *extension,
g_string_append_printf (part_id, ".alternative-prefer-plain.%d", i);
if (camel_content_type_is (ct, "text", "html")) {
-
if (emp_pp->mode != PREFER_HTML) {
if (emp_pp->show_suppressed) {
- sparts = make_part_attachment (
- parser, sp, part_id,
- FALSE, cancellable);
+ make_part_attachment (
+ parser, sp, part_id, FALSE,
+ cancellable, &work_queue);
}
} else {
- sparts = e_mail_parser_parse_part (
- parser, sp, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, sp, part_id,
+ cancellable, &work_queue);
}
- parts = g_slist_concat (parts, sparts);
- continue;
- }
-
- if (camel_content_type_is (ct, "text", "plain")) {
-
- sparts = e_mail_parser_parse_part (
- parser, sp, part_id, cancellable);
-
- plain_text_parts = g_slist_concat (plain_text_parts, sparts);
- continue;
- }
+ } else if (camel_content_type_is (ct, "text", "plain")) {
+ e_mail_parser_parse_part (
+ parser, sp, part_id,
+ cancellable, &plain_text_parts);
/* Always show calendar part! */
- if (camel_content_type_is (ct, "text", "calendar") ||
+ } else if (camel_content_type_is (ct, "text", "calendar") ||
camel_content_type_is (ct, "text", "x-calendar")) {
- /* Hide everything else, displaying native calendar part only */
- hide_parts (parts);
+ /* Hide everything else, displaying
+ * native calendar part only. */
+ hide_parts (&work_queue);
- sparts = e_mail_parser_parse_part (
- parser, sp, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, sp, part_id, cancellable, &work_queue);
- parts = g_slist_concat (parts, sparts);
has_calendar = TRUE;
- continue;
- }
/* Multiparts can represent a text/html with inline images or so */
- if (camel_content_type_is (ct, "multipart", "*")) {
- GSList *iter;
+ } else if (camel_content_type_is (ct, "multipart", "*")) {
+ GQueue inner_queue = G_QUEUE_INIT;
+ GList *head, *link;
gboolean has_html = FALSE;
- sparts = e_mail_parser_parse_part (
- parser, sp, part_id, cancellable);
+ e_mail_parser_parse_part (
+ parser, sp, part_id, cancellable, &inner_queue);
+
+ head = g_queue_peek_head_link (&inner_queue);
/* Check whether the multipart contains a text/html part */
- for (iter = sparts; iter; iter = g_slist_next (iter)) {
- EMailPart *p = iter->data;
- if (!p)
- continue;
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *mail_part = link->data;
- if (strstr (p->id, ".text_html") != NULL) {
+ if (strstr (mail_part->id, ".text_html") != NULL) {
has_html = TRUE;
break;
}
@@ -294,41 +287,41 @@ empe_prefer_plain_parse (EMailParserExtension *extension,
if (has_html && (emp_pp->mode != PREFER_HTML)) {
if (emp_pp->show_suppressed) {
- sparts = e_mail_parser_wrap_as_attachment (
- parser, sp, sparts, part_id,
- cancellable);
+ e_mail_parser_wrap_as_attachment (
+ parser, sp, part_id,
+ &inner_queue);
} else {
- hide_parts (sparts);
+ hide_parts (&inner_queue);
}
}
- parts = g_slist_concat (parts, sparts);
- continue;
- }
+ e_queue_transfer (&inner_queue, &work_queue);
/* Parse everything else as an attachment */
- sparts = e_mail_parser_parse_part (
- parser, sp, part_id, cancellable);
- parts = g_slist_concat (
- parts,
- e_mail_parser_wrap_as_attachment (
- parser, sp, sparts, part_id,
- cancellable));
+ } else {
+ GQueue inner_queue = G_QUEUE_INIT;
+
+ e_mail_parser_parse_part (
+ parser, sp, part_id,
+ cancellable, &inner_queue);
+ e_mail_parser_wrap_as_attachment (
+ parser, sp, part_id, &inner_queue);
+
+ e_queue_transfer (&inner_queue, &work_queue);
+ }
}
/* Don't hide the plain text if there's nothing else to display */
- if (has_calendar || (nparts > 1 && emp_pp->mode == PREFER_HTML)) {
- hide_parts (plain_text_parts);
- }
+ if (has_calendar || (nparts > 1 && emp_pp->mode == PREFER_HTML))
+ hide_parts (&plain_text_parts);
- if (plain_text_parts) {
- /* plain_text parts should be always first */
- parts = g_slist_concat (plain_text_parts, parts);
- }
+ /* plain_text parts should be always first */
+ e_queue_transfer (&plain_text_parts, out_mail_parts);
+ e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, partidlen);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/modules/text-highlight/e-mail-parser-text-highlight.c b/modules/text-highlight/e-mail-parser-text-highlight.c
index 69aa1ccff2..eb56162a3d 100644
--- a/modules/text-highlight/e-mail-parser-text-highlight.c
+++ b/modules/text-highlight/e-mail-parser-text-highlight.c
@@ -58,21 +58,20 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (
E_TYPE_MAIL_PARSER_EXTENSION,
e_mail_parser_parser_extension_interface_init));
-static GSList *
+static gboolean
empe_text_highlight_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
- GSList *parts;
- gint len;
CamelContentType *ct;
+ gint len;
/* Prevent recursion */
- if (strstr (part_id->str, ".text-highlight") != NULL) {
- return NULL;
- }
+ if (strstr (part_id->str, ".text-highlight") != NULL)
+ return FALSE;
/* Don't parse text/html if it's not an attachment */
ct = camel_mime_part_get_content_type (part);
@@ -80,9 +79,8 @@ empe_text_highlight_parse (EMailParserExtension *extension,
const CamelContentDisposition *disp;
disp = camel_mime_part_get_content_disposition (part);
- if (!disp || (g_strcmp0 (disp->disposition, "attachment") != 0)) {
- return NULL;
- }
+ if (!disp || (g_strcmp0 (disp->disposition, "attachment") != 0))
+ return FALSE;
}
len = part_id->len;
@@ -90,12 +88,14 @@ empe_text_highlight_parse (EMailParserExtension *extension,
/* All source codes and scripts are in general plain texts,
* so let text/plain parser handle it. */
- parts = e_mail_parser_parse_part_as (
- parser, part, part_id, "text/plain", cancellable);
+
+ e_mail_parser_parse_part_as (
+ parser, part, part_id, "text/plain",
+ cancellable, out_mail_parts);
g_string_truncate (part_id, len);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/modules/tnef-attachment/e-mail-parser-tnef-attachment.c b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
index 3de54e627f..a0342aaa37 100644
--- a/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
+++ b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
@@ -114,12 +114,13 @@ sanitize_filename (const gchar *filename)
}
}
-static GSList *
+static gboolean
empe_tnef_attachment_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
gchar *tmpdir, *name;
CamelStream *out;
@@ -130,30 +131,30 @@ empe_tnef_attachment_parse (EMailParserExtension *extension,
CamelDataWrapper *content;
gint len;
TNEFStruct tnef;
- GSList *parts;
+ GQueue work_queue = G_QUEUE_INIT;
tmpdir = e_mkdtemp ("tnef-attachment-XXXXXX");
if (tmpdir == NULL)
- return NULL;
+ return FALSE;
name = g_build_filename (tmpdir, ".evo-attachment.tnef", NULL);
out = camel_stream_fs_new_with_name (name, O_RDWR | O_CREAT, 0666, NULL);
if (out == NULL) {
g_free (name);
- return NULL;
+ return FALSE;
}
content = camel_medium_get_content ((CamelMedium *) part);
if (content == NULL) {
g_free (name);
g_object_unref (out);
- return NULL;
+ return FALSE;
}
if (camel_data_wrapper_decode_to_stream_sync (content, out, NULL, NULL) == -1
|| camel_stream_close (out, NULL, NULL) == -1) {
g_object_unref (out);
g_free (name);
- return NULL;
+ return FALSE;
}
g_object_unref (out);
@@ -172,7 +173,7 @@ empe_tnef_attachment_parse (EMailParserExtension *extension,
if (dir == NULL) {
g_object_unref (out);
g_free (name);
- return NULL;
+ return FALSE;
}
mainpart = camel_mime_part_new ();
@@ -226,7 +227,6 @@ empe_tnef_attachment_parse (EMailParserExtension *extension,
len = part_id->len;
g_string_append_printf (part_id, ".tnef");
- parts = NULL;
if (camel_multipart_get_number (mp) > 0) {
CamelMimePart *part = camel_mime_part_new ();
@@ -235,18 +235,20 @@ empe_tnef_attachment_parse (EMailParserExtension *extension,
(CamelMedium *) part,
CAMEL_DATA_WRAPPER (mp));
- 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, &work_queue);
g_object_unref (part);
}
g_string_truncate (part_id, len);
- if (parts)
- parts = e_mail_parser_wrap_as_attachment (
- parser, part, parts, part_id, cancellable);
+ if (!g_queue_is_empty (&work_queue))
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
g_object_unref (mp);
g_object_unref (mainpart);
@@ -254,7 +256,7 @@ empe_tnef_attachment_parse (EMailParserExtension *extension,
g_free (name);
g_free (tmpdir);
- return parts;
+ return TRUE;
}
static const gchar **
diff --git a/modules/vcard-inline/e-mail-parser-vcard-inline.c b/modules/vcard-inline/e-mail-parser-vcard-inline.c
index 319775b6eb..84f4f2f538 100644
--- a/modules/vcard-inline/e-mail-parser-vcard-inline.c
+++ b/modules/vcard-inline/e-mail-parser-vcard-inline.c
@@ -328,39 +328,46 @@ decode_vcard (EMailPartVCardInline *vcard_part,
g_object_unref (stream);
}
-static GSList *
+static gboolean
empe_vcard_inline_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
- GCancellable *cancellable)
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
{
EMailPartVCardInline *vcard_part;
+ GQueue work_queue = G_QUEUE_INIT;
gint len;
len = part_id->len;
g_string_append (part_id, ".org-gnome-vcard-inline-display");
vcard_part = (EMailPartVCardInline *) e_mail_part_subclass_new (
- part, part_id->str, sizeof (EMailPartVCardInline),
- (GFreeFunc) mail_part_vcard_inline_free);
+ part, part_id->str, sizeof (EMailPartVCardInline),
+ (GFreeFunc) mail_part_vcard_inline_free);
vcard_part->parent.mime_type = camel_content_type_simple (
- camel_mime_part_get_content_type (part));
+ camel_mime_part_get_content_type (part));
vcard_part->parent.bind_func = (EMailPartDOMBindFunc) bind_dom;
vcard_part->parent.is_attachment = TRUE;
vcard_part->formatter = g_object_new (
- EAB_TYPE_CONTACT_FORMATTER,
- "display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT,
- "render-maps", FALSE, NULL);
+ EAB_TYPE_CONTACT_FORMATTER,
+ "display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ "render-maps", FALSE, NULL);
g_object_ref (part);
decode_vcard (vcard_part, part);
g_string_truncate (part_id, len);
- return e_mail_parser_wrap_as_attachment (
- parser, part, g_slist_append (NULL, vcard_part),
- part_id, cancellable);
+ g_queue_push_tail (&work_queue, vcard_part);
+
+ e_mail_parser_wrap_as_attachment (
+ parser, part, part_id, &work_queue);
+
+ e_queue_transfer (&work_queue, out_mail_parts);
+
+ return TRUE;
}
static guint32