diff options
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | camel/camel-data-wrapper.c | 20 | ||||
-rw-r--r-- | camel/camel-mime-message.c | 28 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 68 | ||||
-rw-r--r-- | camel/camel-multipart.c | 44 | ||||
-rw-r--r-- | camel/camel-simple-data-wrapper.c | 18 | ||||
-rw-r--r-- | camel/gmime-content-field.c | 81 | ||||
-rw-r--r-- | camel/gmime-content-field.h | 5 | ||||
-rw-r--r-- | tests/ui-tests/store_listing.c | 7 |
9 files changed, 249 insertions, 43 deletions
@@ -1,4 +1,23 @@ -1999-08-09 bertrand <Bertrand.Guiheneuf@aful.org> +1999-08-11 bertrand <Bertrand.Guiheneuf@aful.org> + + * camel/camel-multipart.c (_finalize): + * camel/camel-simple-data-wrapper.c (_finalize): + * camel/camel-mime-part.c (_finalize): + implemented destructors. + + * camel/gmime-content-field.c (gmime_content_field_ref): + (gmime_content_field_unref): + New reference mechanism for GMimeContentField objects. + + * camel/camel-data-wrapper.c (_finalize): + Started implementing destructors. + + * camel/camel-mime-part.c (_construct_from_stream): + * camel/gmime-content-field.c (gmime_content_field_write_to_stream): + * camel/camel-multipart.c (_construct_from_stream): + removed forgotten anarchic traces. + +1999-08-10 bertrand <Bertrand.Guiheneuf@aful.org> * tests/ui-tests/store_listing.c: * tests/ui-tests/store_listing.glade: diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c index ef8c325293..579f32f023 100644 --- a/camel/camel-data-wrapper.c +++ b/camel/camel-data-wrapper.c @@ -38,11 +38,13 @@ static void _set_mime_type (CamelDataWrapper *data_wrapper, gchar *mime_type); static gchar *_get_mime_type (CamelDataWrapper *data_wrapper); static GMimeContentField *_get_mime_type_field (CamelDataWrapper *data_wrapper); static void _set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type); - +static void _finalize (GtkObject *object); static void camel_data_wrapper_class_init (CamelDataWrapperClass *camel_data_wrapper_class) { + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_data_wrapper_class); + parent_class = gtk_type_class (gtk_object_get_type ()); /* virtual method definition */ @@ -52,7 +54,9 @@ camel_data_wrapper_class_init (CamelDataWrapperClass *camel_data_wrapper_class) camel_data_wrapper_class->get_mime_type = _get_mime_type; camel_data_wrapper_class->get_mime_type_field = _get_mime_type_field; camel_data_wrapper_class->set_mime_type_field = _set_mime_type_field; + /* virtual method overload */ + gtk_object_class->finalize = _finalize; } @@ -96,6 +100,20 @@ camel_data_wrapper_get_type (void) } +static void +_finalize (GtkObject *object) +{ + CamelDataWrapper *camel_data_wrapper = CAMEL_DATA_WRAPPER (object); + + CAMEL_LOG_FULL_DEBUG ("Entering CamelDataWrapper::finalize\n"); + printf ("CamelDataWrapper::finalize, finalizing object %p\n", object); + if (camel_data_wrapper->mime_type) + gmime_content_field_unref (camel_data_wrapper->mime_type); + + parent_class->finalize (object); + CAMEL_LOG_FULL_DEBUG ("Leaving CamelDataWrapper::finalize\n"); +} + /** * _write_to_stream: write data content in a byte stream diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index a6ff2482a6..1563c0cb1d 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -74,6 +74,8 @@ static guint _get_message_number (CamelMimeMessage *mime_message); static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static gboolean _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_value); +static void _finalize (GtkObject *object); + /* Returns the class for a CamelMimeMessage */ #define CMM_CLASS(so) CAMEL_MIME_MESSAGE_CLASS (GTK_OBJECT(so)->klass) #define CDW_CLASS(so) CAMEL_DATA_WRAPPER_CLASS (GTK_OBJECT(so)->klass) @@ -97,6 +99,7 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) { CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_message_class); CamelMimePartClass *camel_mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_class); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_data_wrapper_class); parent_class = gtk_type_class (camel_mime_part_get_type ()); _init_header_name_table(); @@ -129,6 +132,7 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) camel_data_wrapper_class->write_to_stream = _write_to_stream; camel_mime_part_class->parse_header_pair = _parse_header_pair; + gtk_object_class->finalize = _finalize; } @@ -168,12 +172,36 @@ camel_mime_message_get_type (void) } +static void +_finalize (GtkObject *object) +{ + CamelMimeMessage *message = CAMEL_MIME_MESSAGE (object); + + CAMEL_LOG_FULL_DEBUG ("Entering CamelMimeMessage::finalize\n"); + if (message->received_date) g_free (message->received_date); + if (message->sent_date) g_free (message->sent_date); + if (message->subject) g_free (message->subject); + if (message->reply_to) g_free (message->reply_to); + if (message->from) g_free (message->from); + +#warning free recipients and flags. + if (message->folder) gtk_object_unref (GTK_OBJECT (message->folder)); + if (message->session) gtk_object_unref (GTK_OBJECT (message->session)); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); + CAMEL_LOG_FULL_DEBUG ("Leaving CamelMimeMessage::finalize\n"); +} + + + CamelMimeMessage * camel_mime_message_new_with_session (CamelSession *session) { CamelMimeMessage *mime_message; mime_message = gtk_type_new (CAMEL_MIME_MESSAGE_TYPE); mime_message->session = session; + if (session) gtk_object_ref (GTK_OBJECT (session)); + return mime_message; } diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 39cdbe5cba..fb1caaa70c 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -80,6 +80,7 @@ static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *strea static gboolean _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_value); void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); +static void _finalize (GtkObject *object); /* loads in a hash table the set of header names we */ /* recognize and associate them with a unique enum */ @@ -101,6 +102,8 @@ static void camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) { CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_part_class); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_data_wrapper_class); + parent_class = gtk_type_class (camel_data_wrapper_get_type ()); _init_header_name_table(); @@ -136,6 +139,8 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) /* virtual method overload */ camel_data_wrapper_class->write_to_stream = _write_to_stream; camel_data_wrapper_class->construct_from_stream = _construct_from_stream; + + gtk_object_class->finalize = _finalize; } static void @@ -175,6 +180,39 @@ camel_mime_part_get_type (void) } +static void +_finalize (GtkObject *object) +{ + CamelMimePart *mime_part = CAMEL_MIME_PART (object); + +#warning do something for (mime_part->disposition) which should not be a GMimeContentField + + CAMEL_LOG_FULL_DEBUG ("Entering CamelMimePart::finalize\n"); + + if (mime_part->headers) { +#warning Free hash table elements + g_hash_table_destroy (mime_part->headers); + } + + if (mime_part->description) g_free (mime_part->description); + if (mime_part->disposition) gmime_content_field_unref (mime_part->disposition); + if (mime_part->content_id) g_free (mime_part->content_id); + if (mime_part->content_MD5) g_free (mime_part->content_MD5); + if (mime_part->content_languages) string_list_free (mime_part->content_languages); + if (mime_part->encoding) g_free (mime_part->encoding); + if (mime_part->filename) g_free (mime_part->filename); + if (mime_part->header_lines) string_list_free (mime_part->header_lines); + + if (mime_part->content_type) gmime_content_field_unref (mime_part->content_type); + if (mime_part->content) { + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::finalize, unreferencing content object\n"); + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::finalize,Destroying object %p\n", mime_part->content); + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::finalize, object type : %s\n", gtk_type_name (GTK_OBJECT_TYPE (mime_part->content))); + gtk_object_unref (GTK_OBJECT (mime_part->content)); + } + GTK_OBJECT_CLASS (parent_class)->finalize (object); + CAMEL_LOG_FULL_DEBUG ("Leaving CamelMimePart::finalize\n"); +} static void @@ -546,8 +584,9 @@ _set_content_object(CamelMimePart *mime_part, CamelDataWrapper *content) mime_part->content = content; object_content_field = camel_data_wrapper_get_mime_type_field (content); if (mime_part->content_type && (mime_part->content_type != object_content_field)) - gmime_content_field_free (mime_part->content_type); + gmime_content_field_unref (mime_part->content_type); mime_part->content_type = object_content_field; + gmime_content_field_ref (object_content_field); CAMEL_LOG_FULL_DEBUG ("Leaving CamelMimePart::set_content_object\n"); } @@ -757,26 +796,28 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream parsing content\n"); content_type = camel_mime_part_get_content_type (mime_part); mime_type = gmime_content_field_get_mime_type (content_type); - printf ("Content-Type address = %p\n", content_type); + if (!mime_type) { CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream content type field not found " "using default \"text/plain\"\n"); mime_type = g_strdup ("text/plain"); camel_mime_part_set_content_type (mime_part, mime_type); } - content_object_type = data_wrapper_repository_get_data_wrapper_type (mime_type); - - CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream content type object type used: %s\n", gtk_type_name (content_object_type)); - g_free (mime_type); - content_object = CAMEL_DATA_WRAPPER (gtk_type_new (content_object_type)); - camel_data_wrapper_set_mime_type_field (content_object, camel_mime_part_get_content_type (mime_part)); - camel_mime_part_set_content_object (mime_part, content_object); - camel_data_wrapper_construct_from_stream (content_object, stream); - + content_object_type = data_wrapper_repository_get_data_wrapper_type (mime_type); - - CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream content parsed\n"); + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream content type object type used: %s\n", gtk_type_name (content_object_type)); + g_free (mime_type); + content_object = CAMEL_DATA_WRAPPER (gtk_type_new (content_object_type)); + camel_data_wrapper_set_mime_type_field (content_object, camel_mime_part_get_content_type (mime_part)); + camel_mime_part_set_content_object (mime_part, content_object); + camel_data_wrapper_construct_from_stream (content_object, stream); + /* the object is referenced in the set_content_object method, so unref it here */ + gtk_object_unref (GTK_OBJECT (content_object)); + + + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream content parsed\n"); + CAMEL_LOG_FULL_DEBUG ("CamelMimePart:: Leaving _construct_from_stream\n"); } @@ -812,6 +853,7 @@ camel_mime_part_set_text (CamelMimePart *camel_mime_part, gchar *text) camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (simple_data_wrapper), "text/plain"); camel_simple_data_wrapper_set_text ( simple_data_wrapper, text); camel_mime_part_set_content_object (camel_mime_part, CAMEL_DATA_WRAPPER (simple_data_wrapper)); + gtk_object_unref (GTK_OBJECT (simple_data_wrapper)); } else camel_mime_part->content = NULL; CAMEL_LOG_FULL_DEBUG ("CamelMimePart:: Leaving camel_mime_part_set_text\n"); diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c index 20a790465c..17f79cdd97 100644 --- a/camel/camel-multipart.c +++ b/camel/camel-multipart.c @@ -43,6 +43,8 @@ static const gchar *_get_boundary (CamelMultipart *multipart); static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); +static void _finalize (GtkObject *object); + static CamelDataWrapperClass *parent_class=NULL; /* Returns the class for a CamelMultipart */ @@ -56,6 +58,8 @@ static void camel_multipart_class_init (CamelMultipartClass *camel_multipart_class) { CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_multipart_class); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_multipart_class); + parent_class = gtk_type_class (camel_data_wrapper_get_type ()); /* virtual method definition */ @@ -73,6 +77,8 @@ camel_multipart_class_init (CamelMultipartClass *camel_multipart_class) /* virtual method overload */ camel_data_wrapper_class->write_to_stream = _write_to_stream; camel_data_wrapper_class->construct_from_stream = _construct_from_stream; + + gtk_object_class->finalize = _finalize; } static void @@ -113,6 +119,33 @@ camel_multipart_get_type (void) return camel_multipart_type; } +static void +_unref_part (gpointer data, gpointer user_data) +{ + GtkObject *body_part = GTK_OBJECT (data); + + gtk_object_unref (body_part); +} + +static void +_finalize (GtkObject *object) +{ + CamelMultipart *multipart = CAMEL_MULTIPART (object); + + CAMEL_LOG_FULL_DEBUG ("Entering CamelMultipart::finalize\n"); + + if (multipart->parent) gtk_object_unref (GTK_OBJECT (multipart->parent)); + + g_list_foreach (multipart->parts, _unref_part, NULL); + + if (multipart->boundary) g_free (multipart->boundary); + if (multipart->preface) g_free (multipart->preface); + if (multipart->postface) g_free (multipart->postface); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); + CAMEL_LOG_FULL_DEBUG ("Leaving CamelMultipart::finalize\n"); +} + CamelMultipart * camel_multipart_new () @@ -123,7 +156,8 @@ camel_multipart_new () multipart = (CamelMultipart *)gtk_type_new (CAMEL_MULTIPART_TYPE); multipart->preface = NULL; multipart->postface = NULL; - + + CAMEL_LOG_FULL_DEBUG ("CamelMultipart:: Leaving new()\n"); return multipart; } @@ -133,6 +167,7 @@ static void _add_part (CamelMultipart *multipart, CamelMimeBodyPart *part) { multipart->parts = g_list_append (multipart->parts, part); + if (part) gtk_object_ref (GTK_OBJECT (part)); } void @@ -146,6 +181,7 @@ static void _add_part_at (CamelMultipart *multipart, CamelMimeBodyPart *part, guint index) { multipart->parts = g_list_insert (multipart->parts, part, index); + if (part) gtk_object_ref (GTK_OBJECT (part)); } void @@ -162,6 +198,7 @@ _remove_part (CamelMultipart *multipart, CamelMimeBodyPart *part) return; } multipart->parts = g_list_remove (multipart->parts, part); + if (part) gtk_object_unref (GTK_OBJECT (part)); } void @@ -197,8 +234,9 @@ _remove_part_at (CamelMultipart *multipart, guint index) removed_body_part = CAMEL_MIME_BODY_PART (part_to_remove->data); multipart->parts = g_list_remove_link (parts_list, part_to_remove); + if (part_to_remove->data) gtk_object_unref (GTK_OBJECT (part_to_remove->data)); g_list_free_1 (part_to_remove); - + CAMEL_LOG_FULL_DEBUG ("CamelMultipart:: Leaving remove_part_at\n"); return removed_body_part; @@ -252,6 +290,7 @@ static void _set_parent (CamelMultipart *multipart, CamelMimePart *parent) { multipart->parent = parent; + if (parent) gtk_object_ref (GTK_OBJECT (parent)); } void @@ -390,7 +429,6 @@ _read_part (CamelStream *new_part_stream, CamelStream *stream, gchar *normal_bou new_line = gmime_read_line_from_stream (stream); while (new_line && !end_of_part && !last_part) { - printf ("++ new line = \"%s\"\n", new_line); end_of_part = (strcmp (new_line, normal_boundary) == 0); last_part = (strcmp (new_line, end_boundary) == 0); if (!end_of_part && !last_part) { diff --git a/camel/camel-simple-data-wrapper.c b/camel/camel-simple-data-wrapper.c index a2203a52e8..99bd0b2075 100644 --- a/camel/camel-simple-data-wrapper.c +++ b/camel/camel-simple-data-wrapper.c @@ -32,18 +32,22 @@ static CamelDataWrapperClass *parent_class=NULL; static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); +static void _finalize (GtkObject *object); static void camel_simple_data_wrapper_class_init (CamelSimpleDataWrapperClass *camel_simple_data_wrapper_class) { CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_simple_data_wrapper_class); - + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_data_wrapper_class); + parent_class = gtk_type_class (camel_data_wrapper_get_type ()); /* virtual method definition */ /* virtual method overload */ camel_data_wrapper_class->write_to_stream = _write_to_stream; camel_data_wrapper_class->construct_from_stream = _construct_from_stream; + + gtk_object_class->finalize = _finalize; } @@ -76,6 +80,18 @@ camel_simple_data_wrapper_get_type (void) } +static void +_finalize (GtkObject *object) +{ + CamelSimpleDataWrapper *simple_data_wrapper = CAMEL_SIMPLE_DATA_WRAPPER (object); + + CAMEL_LOG_FULL_DEBUG ("Entering CamelMimePart::finalize\n"); + if (simple_data_wrapper->byte_array) g_byte_array_free (simple_data_wrapper->byte_array, TRUE); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); + CAMEL_LOG_FULL_DEBUG ("Leaving CamelMimePart::finalize\n"); +} + /** * camel_simple_data_wrapper_new: create a new CamelSimpleDataWrapper object diff --git a/camel/gmime-content-field.c b/camel/gmime-content-field.c index 285926e702..04b07b7626 100644 --- a/camel/gmime-content-field.c +++ b/camel/gmime-content-field.c @@ -50,11 +50,72 @@ gmime_content_field_new (const gchar *type, const gchar *subtype) ctf->type = g_strdup (type); ctf->subtype = g_strdup (subtype); ctf->parameters = g_hash_table_new (g_str_hash, g_str_equal); - + ctf->ref = 1; + return ctf; } +static void +_free_parameter (gpointer name, gpointer value, gpointer user_data) +{ + g_free (name); + g_free (value); +} + +/** + * gmime_content_field_free: free a GMimeContentField object + * @content_field: GMimeContentField object + * + * This method destroys the object and should be used very carefully. + * Use gmime_content_field_unref instead. + * + **/ +void +gmime_content_field_free (GMimeContentField *content_field) +{ + g_hash_table_foreach (content_field->parameters, _free_parameter, NULL); + g_free (content_field->type); + g_free (content_field->subtype); + g_hash_table_destroy (content_field->parameters); + g_free (content_field); +} + +/** + * gmime_content_field_ref: add a reference to a GMimeContentField object + * @content_field: GMimeContentField object + * + * Tell a GMimeContentField object that something holds a reference + * on him. This, coupled with the corresponding + * gmime_content_field_unref() method allow several + * objects to use the same GMimeContentField object. + **/ +void +gmime_content_field_ref (GMimeContentField *content_field) +{ + content_field->ref += 1; +} + +/** + * gmime_content_field_unref: remove a reference to a GMimeContentField object + * @content_field: GMimeContentField object + * + * Tell a GMimeContentField object that something which + * was holding a reference to him does not need it anymore. + * When no more reference exist, the GMimeContentField object + * is freed using gmime_content_field_free(). + * + **/ +void +gmime_content_field_unref (GMimeContentField *content_field) +{ + content_field->ref -= 1; + if (content_field->ref <= 0) + gmime_content_field_free (content_field); +} + + + /** * gmime_content_field_set_parameter: set a parameter for a GMimeContentField object * @content_field: content field @@ -125,7 +186,6 @@ gmime_content_field_write_to_stream (GMimeContentField *content_field, CamelStre if (!content_field) return; g_assert (stream); - printf ("Content-field address = %p\n", content_field); if (content_field->type) { camel_stream_write_strings (stream, "Content-Type: ", content_field->type, NULL); if (content_field->subtype) { @@ -304,20 +364,3 @@ gmime_content_field_construct_from_string (GMimeContentField *content_field, con } - -static void -_free_parameter (gpointer name, gpointer value, gpointer user_data) -{ - g_free (name); - g_free (value); -} - -void -gmime_content_field_free (GMimeContentField *content_field) -{ - g_hash_table_foreach (content_field->parameters, _free_parameter, NULL); - g_free (content_field->type); - g_free (content_field->subtype); - g_hash_table_destroy (content_field->parameters); - g_free (content_field); -} diff --git a/camel/gmime-content-field.h b/camel/gmime-content-field.h index 663c747291..01045545ec 100644 --- a/camel/gmime-content-field.h +++ b/camel/gmime-content-field.h @@ -41,9 +41,14 @@ typedef struct { gchar *subtype; GHashTable *parameters; + gint ref; + } GMimeContentField; GMimeContentField *gmime_content_field_new (const gchar *type, const gchar *subtype); +void gmime_content_field_ref (GMimeContentField *content_field); +void gmime_content_field_unref (GMimeContentField *content_field); + void gmime_content_field_set_parameter (GMimeContentField *content_field, const gchar *attribute, const gchar *value); void gmime_content_field_write_to_stream (GMimeContentField *content_field, CamelStream *stream); void gmime_content_field_construct_from_string (GMimeContentField *content_field, const gchar *string); diff --git a/tests/ui-tests/store_listing.c b/tests/ui-tests/store_listing.c index 64f95f0b1d..34c0e51a28 100644 --- a/tests/ui-tests/store_listing.c +++ b/tests/ui-tests/store_listing.c @@ -3,11 +3,8 @@ -/* - gcc -o store_listing `gnome-config --cflags gnomeui libglade` \ - store_listing.c `gnome-config --libs gnomeui libglade` -*/ -/******************************************************************************/ +/* A simple and very dirty hack written to test + (and perhaps demonstrate) Camel */ #include <gnome.h> |