[gmime] use event listeners to uncache message headers
- From: Jeffrey Stedfast <fejj src gnome org>
- To: svn-commits-list gnome org
- Subject: [gmime] use event listeners to uncache message headers
- Date: Wed, 29 Apr 2009 07:49:35 -0400 (EDT)
commit da11b4a11fb4b278c2e8fa96a31cca603cafc684
Author: Jeffrey Stedfast <fejj gnome org>
Date: Wed Apr 29 07:47:07 2009 -0400
use event listeners to uncache message headers
2009-04-29 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-events.[c,h]: Don't require a GObject owner.
* gmime/gmime-message.c (g_mime_message_set_mime_part): Add a
mime_part_headers_changed listener.
(g_mime_message_finalize): Remove the listener.
(mime_part_headers_changed): Uncache the message header stream.
(message_get_headers): Removed hack.
(message_write_to_stream): Same.
* gmime/gmime-header.c (g_mime_header_list_set_stream): Emit a
changed event.
(g_mime_header_iter_set_value): Call set_stream() instead of
setting the stream to NULL ourselves. Also causes a changed event
to be emitted.
(g_mime_header_list_prepend): Same.
(g_mime_header_list_append): Here too.
(g_mime_header_list_set): And here.
(g_mime_header_list_remove): Same.
---
ChangeLog | 19 +++++++++++++++++++
gmime/gmime-events.c | 6 +++---
gmime/gmime-events.h | 5 ++---
gmime/gmime-header.c | 41 ++++++++++++++++++++++++-----------------
gmime/gmime-message.c | 42 ++++++++++++++++++++++++++++--------------
5 files changed, 76 insertions(+), 37 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2259191..2f1e727 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2009-04-29 Jeffrey Stedfast <fejj novell com>
+
+ * gmime/gmime-message.c (g_mime_message_set_mime_part): Add a
+ mime_part_headers_changed listener.
+ (g_mime_message_finalize): Remove the listener.
+ (mime_part_headers_changed): Uncache the message header stream.
+ (message_get_headers): Removed hack.
+ (message_write_to_stream): Same.
+
+ * gmime/gmime-header.c (g_mime_header_list_set_stream): Emit a
+ changed event.
+ (g_mime_header_iter_set_value): Call set_stream() instead of
+ setting the stream to NULL ourselves. Also causes a changed event
+ to be emitted.
+ (g_mime_header_list_prepend): Same.
+ (g_mime_header_list_append): Here too.
+ (g_mime_header_list_set): And here.
+ (g_mime_header_list_remove): Same.
+
2009-04-28 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-part.c (g_mime_part_get_best_content_encoding): New
diff --git a/gmime/gmime-events.c b/gmime/gmime-events.c
index fcfbbf4..3ce74fa 100644
--- a/gmime/gmime-events.c
+++ b/gmime/gmime-events.c
@@ -57,21 +57,21 @@ event_listener_free (EventListener *listener)
struct _GMimeEvent {
- GObject *owner;
+ gpointer owner;
List list;
};
/**
* g_mime_event_new:
- * @owner: a #GObject; typically the one that will own this event
+ * @owner: a pointer to the object owning this event
*
* Creates a new #GMimeEvent context.
*
* Returns: a newly allocated #GMimeEvent context.
**/
GMimeEvent *
-g_mime_event_new (GObject *owner)
+g_mime_event_new (gpointer owner)
{
GMimeEvent *event;
diff --git a/gmime/gmime-events.h b/gmime/gmime-events.h
index 1755075..4100795 100644
--- a/gmime/gmime-events.h
+++ b/gmime/gmime-events.h
@@ -23,15 +23,14 @@
#define __GMIME_EVENTS_H__
#include <glib.h>
-#include <glib-object.h>
G_BEGIN_DECLS
-typedef void (* GMimeEventCallback) (GObject *sender, gpointer args, gpointer user_data);
+typedef void (* GMimeEventCallback) (gpointer sender, gpointer args, gpointer user_data);
typedef struct _GMimeEvent GMimeEvent;
-G_GNUC_INTERNAL GMimeEvent *g_mime_event_new (GObject *owner);
+G_GNUC_INTERNAL GMimeEvent *g_mime_event_new (gpointer owner);
G_GNUC_INTERNAL void g_mime_event_destroy (GMimeEvent *event);
G_GNUC_INTERNAL void g_mime_event_add (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data);
diff --git a/gmime/gmime-header.c b/gmime/gmime-header.c
index 23e5014..18397ec 100644
--- a/gmime/gmime-header.c
+++ b/gmime/gmime-header.c
@@ -26,10 +26,11 @@
#include <string.h>
#include <ctype.h>
+#include "gmime-stream-mem.h"
#include "gmime-common.h"
#include "gmime-header.h"
+#include "gmime-events.h"
#include "gmime-utils.h"
-#include "gmime-stream-mem.h"
#include "list.h"
@@ -67,6 +68,7 @@ struct _GMimeHeader {
struct _GMimeHeaderList {
GMimeStream *stream;
GHashTable *writers;
+ GMimeEvent *changed;
GHashTable *hash;
guint32 version;
List list;
@@ -534,6 +536,7 @@ g_mime_header_list_new (void)
headers->hash = g_hash_table_new (g_mime_strcase_hash,
g_mime_strcase_equal);
list_init (&headers->list);
+ headers->changed = g_mime_event_new (headers);
headers->stream = NULL;
headers->version = 0;
@@ -568,6 +571,8 @@ g_mime_header_list_destroy (GMimeHeaderList *headers)
if (headers->stream)
g_object_unref (headers->stream);
+ g_mime_event_destroy (headers->changed);
+
g_slice_free (GMimeHeaderList, headers);
}
@@ -594,10 +599,7 @@ g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const ch
list_append (&headers->list, (ListNode *) header);
g_hash_table_replace (headers->hash, header->name, header);
- if (headers->stream) {
- g_object_unref (headers->stream);
- headers->stream = NULL;
- }
+ g_mime_header_list_set_stream (headers, NULL);
}
@@ -625,10 +627,7 @@ g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const cha
if (!g_hash_table_lookup (headers->hash, name))
g_hash_table_insert (headers->hash, header->name, header);
- if (headers->stream) {
- g_object_unref (headers->stream);
- headers->stream = NULL;
- }
+ g_mime_header_list_set_stream (headers, NULL);
}
@@ -702,10 +701,7 @@ g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *
g_hash_table_insert (headers->hash, header->name, header);
}
- if (headers->stream) {
- g_object_unref (headers->stream);
- headers->stream = NULL;
- }
+ g_mime_header_list_set_stream (headers, NULL);
}
@@ -749,10 +745,7 @@ g_mime_header_list_remove (GMimeHeaderList *headers, const char *name)
list_unlink ((ListNode *) header);
g_mime_header_free (header);
- if (headers->stream) {
- g_object_unref (headers->stream);
- headers->stream = NULL;
- }
+ g_mime_header_list_set_stream (headers, NULL);
return TRUE;
}
@@ -954,6 +947,9 @@ g_mime_header_list_set_stream (GMimeHeaderList *headers, GMimeStream *stream)
g_return_if_fail (stream == NULL || GMIME_IS_STREAM (stream));
g_return_if_fail (headers != NULL);
+ if (headers->stream == stream)
+ return;
+
if (stream)
g_object_ref (stream);
@@ -961,6 +957,8 @@ g_mime_header_list_set_stream (GMimeHeaderList *headers, GMimeStream *stream)
g_object_unref (headers->stream);
headers->stream = stream;
+
+ g_mime_event_emit (headers->changed, NULL);
}
@@ -979,3 +977,12 @@ g_mime_header_list_get_stream (GMimeHeaderList *headers)
return headers->stream;
}
+
+
+GMimeEvent *
+_g_mime_header_list_get_changed_event (GMimeHeaderList *headers)
+{
+ g_return_val_if_fail (headers != NULL, NULL);
+
+ return headers->changed;
+}
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 66e8b4e..720e92f 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -46,6 +46,7 @@
* A #GMimeMessage represents an rfc822 message.
**/
+extern GMimeEvent *_g_mime_header_list_get_changed_event (GMimeHeaderList *headers);
static void g_mime_message_class_init (GMimeMessageClass *klass);
static void g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass);
@@ -143,6 +144,13 @@ g_mime_message_class_init (GMimeMessageClass *klass)
}
static void
+mime_part_headers_changed (GMimeHeaderList *headers, gpointer args, GMimeMessage *message)
+{
+ /* clear the message's header stream */
+ g_mime_header_list_set_stream (((GMimeObject *) message)->headers, NULL);
+}
+
+static void
connect_changed_event (GMimeMessage *message, GMimeRecipientType type)
{
InternetAddressList *list;
@@ -225,6 +233,7 @@ static void
g_mime_message_finalize (GObject *object)
{
GMimeMessage *message = (GMimeMessage *) object;
+ GMimeEvent *changed;
guint i;
g_free (message->from);
@@ -243,8 +252,11 @@ g_mime_message_finalize (GObject *object)
g_free (message->message_id);
/* unref child mime part */
- if (message->mime_part)
+ if (message->mime_part) {
+ changed = _g_mime_header_list_get_changed_event (message->mime_part->headers);
+ g_mime_event_remove (changed, (GMimeEventCallback) mime_part_headers_changed, message);
g_object_unref (message->mime_part);
+ }
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -943,11 +955,6 @@ message_get_headers (GMimeObject *object)
/* if the mime part has raw headers, then it contains the message headers as well */
g_mime_header_list_write_to_stream (message->mime_part->headers, stream);
} else {
- /* Note: if the user changed the mime_part's headers,
- * we need to unset our cached header stream or it
- * won't reflect the changes. */
- g_mime_header_list_set_stream (object->headers, NULL);
-
g_mime_header_list_write_to_stream (object->headers, stream);
if (message->mime_part) {
if (g_mime_object_get_header (message->mime_part, "Content-Type"))
@@ -972,11 +979,6 @@ message_write_to_stream (GMimeObject *object, GMimeStream *stream)
if (message->mime_part) {
if (!g_mime_header_list_get_stream (message->mime_part->headers)) {
- /* Note: if the user changed the mime_part's headers,
- * we need to unset our cached header stream or it
- * won't reflect the changes. */
- g_mime_header_list_set_stream (object->headers, NULL);
-
if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
return -1;
@@ -1442,17 +1444,29 @@ g_mime_message_get_mime_part (GMimeMessage *message)
void
g_mime_message_set_mime_part (GMimeMessage *message, GMimeObject *mime_part)
{
+ GMimeEvent *changed;
+
+ g_return_if_fail (mime_part == NULL || GMIME_IS_OBJECT (mime_part));
g_return_if_fail (GMIME_IS_MESSAGE (message));
- g_return_if_fail (GMIME_IS_OBJECT (mime_part));
- g_object_ref (mime_part);
- g_mime_header_list_set_stream (mime_part->headers, NULL);
+ if (message->mime_part == mime_part)
+ return;
if (message->mime_part) {
+ changed = _g_mime_header_list_get_changed_event (message->mime_part->headers);
+ g_mime_event_remove (changed, (GMimeEventCallback) mime_part_headers_changed, message);
+
g_mime_header_list_set_stream (message->mime_part->headers, NULL);
g_object_unref (message->mime_part);
}
+ if (mime_part) {
+ changed = _g_mime_header_list_get_changed_event (mime_part->headers);
+ g_mime_header_list_set_stream (mime_part->headers, NULL);
+ g_mime_event_add (changed, (GMimeEventCallback) mime_part_headers_changed, message);
+ g_object_ref (mime_part);
+ }
+
g_mime_header_list_set_stream (((GMimeObject *) message)->headers, NULL);
message->mime_part = mime_part;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]