From e826255bf13255f2b5c626192de4fd10a3885b6f Mon Sep 17 00:00:00 2001 From: bertrand Date: Thu, 26 Aug 1999 15:29:40 +0000 Subject: contruct the content from the buffer before calling CamelMedium 1999-08-26 bertrand * camel/camel-mime-part.c (_get_content_object): contruct the content from the buffer before calling CamelMedium implementation. (_construct_from_stream): Do not construct the content by default, just store the content bytes in a temporary buffer. Content will be constructed only at caller request (when calling CamelMedium::get_content_object) Providers with better access to the messages (mbox/MH ...) will have to provider lighter implementation, that is shall not read content at all unless the caller asks for it (again with get_content). * camel/camel-mime-part-utils.c: new file, groups mime-part related utils. Meant to be used by providers subclassing MimeMessage. (camel_mime_part_construct_headers_from_stream): (camel_mime_part_construct_content_from_stream): no more useless temporary hash table. * camel/camel-mime-part.c (_construct_from_stream): calls mime-part-utils functions now. * camel/gmime-utils.c (_store_header_pair_from_string): do not use hash table to store header, use an array instead. svn path=/trunk/; revision=1145 --- ChangeLog | 12 ++++++++++++ camel/camel-mime-part-utils.c | 31 ++++++++++++++++++++++++++++++ camel/camel-mime-part-utils.h | 2 ++ camel/camel-mime-part.c | 44 +++++++++++++++++++++++++++++++++++++------ camel/camel-mime-part.h | 2 ++ camel/camel-stream-mem.c | 35 ++++++++++++++++++++++++---------- camel/camel-stream-mem.h | 5 +++++ tests/test2.c | 2 +- 8 files changed, 116 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index c17189c6d5..ccc4de365e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 1999-08-26 bertrand + * camel/camel-mime-part.c (_get_content_object): + contruct the content from the buffer before calling + CamelMedium implementation. + (_construct_from_stream): Do not construct the content + by default, just store the content bytes in + a temporary buffer. Content will be constructed only + at caller request (when calling CamelMedium::get_content_object) + Providers with better access to the messages (mbox/MH ...) + will have to provider lighter implementation, that is + shall not read content at all unless the caller asks + for it (again with get_content). + * camel/camel-mime-part-utils.c: new file, groups mime-part related utils. Meant to be used by providers subclassing MimeMessage. diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index 9914964a52..59ae49e595 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -132,3 +132,34 @@ camel_mime_part_construct_content_from_stream (CamelMimePart *mime_part, +void +camel_mime_part_store_stream_in_buffer (CamelMimePart *mime_part, + CamelStream *stream) +{ + gint nb_bytes_read_total = 0; + gint nb_bytes_read_chunk; + GByteArray *buffer; +#define STREAM_READ_CHUNK_SZ 100 + + if (mime_part->temp_message_buffer == NULL) + mime_part->temp_message_buffer = g_byte_array_new (); + + buffer = mime_part->temp_message_buffer; + + g_byte_array_set_size (buffer, nb_bytes_read_total + STREAM_READ_CHUNK_SZ); + nb_bytes_read_chunk = camel_stream_read (stream, + buffer->data + nb_bytes_read_total, + STREAM_READ_CHUNK_SZ); + nb_bytes_read_total += nb_bytes_read_chunk; + + while (nb_bytes_read_chunk) { + g_byte_array_set_size (buffer, nb_bytes_read_total + STREAM_READ_CHUNK_SZ); + nb_bytes_read_chunk = camel_stream_read (stream, + buffer->data + nb_bytes_read_total, + STREAM_READ_CHUNK_SZ); + nb_bytes_read_total += nb_bytes_read_chunk; + } + + g_byte_array_set_size (buffer, nb_bytes_read_total); + +} diff --git a/camel/camel-mime-part-utils.h b/camel/camel-mime-part-utils.h index f3f4d55c82..95f574d385 100644 --- a/camel/camel-mime-part-utils.h +++ b/camel/camel-mime-part-utils.h @@ -39,6 +39,8 @@ void camel_mime_part_construct_headers_from_stream (CamelMimePart *mime_part, void camel_mime_part_construct_content_from_stream (CamelMimePart *mime_part, CamelStream *stream); +void camel_mime_part_store_stream_in_buffer (CamelMimePart *mime_part, + CamelStream *stream); #ifdef __cplusplus diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index ef01a54ba4..8f5255ccb4 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -29,7 +29,8 @@ #include "camel-log.h" #include "gmime-utils.h" #include "camel-simple-data-wrapper.h" - +#include "hash-table-utils.h" +#include "camel-stream-mem.h" typedef enum { HEADER_UNKNOWN, @@ -62,6 +63,7 @@ void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream static void _add_header (CamelMedium *medium, gchar *header_name, gchar *header_value); static void _set_content_object (CamelMedium *medium, CamelDataWrapper *content); +static CamelDataWrapper *_get_content_object (CamelMedium *medium); /* CamelMimePart methods */ static void _set_description (CamelMimePart *mime_part, const gchar *description); @@ -93,7 +95,7 @@ static gboolean _parse_header_pair (CamelMimePart *mime_part, gchar *header_name static void _init_header_name_table() { - header_name_table = g_hash_table_new (g_str_hash, g_str_equal); + header_name_table = g_hash_table_new (g_strcase_hash, g_strcase_equal); g_hash_table_insert (header_name_table, "Content-Description", (gpointer)HEADER_DESCRIPTION); g_hash_table_insert (header_name_table, "Content-Disposition", (gpointer)HEADER_DISPOSITION); g_hash_table_insert (header_name_table, "Content-id", (gpointer)HEADER_CONTENT_ID); @@ -138,6 +140,7 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) /* virtual method overload */ camel_medium_class->add_header = _add_header; camel_medium_class->set_content_object = _set_content_object; + camel_medium_class->get_content_object = _get_content_object; camel_data_wrapper_class->write_to_stream = _write_to_stream; camel_data_wrapper_class->construct_from_stream = _construct_from_stream; @@ -159,6 +162,9 @@ camel_mime_part_init (gpointer object, gpointer klass) camel_mime_part->encoding = NULL; camel_mime_part->filename = NULL; camel_mime_part->header_lines = NULL; + + camel_mime_part->temp_message_buffer = NULL; + } @@ -208,8 +214,9 @@ _finalize (GtkObject *object) 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->temp_message_buffer) g_byte_array_free (mime_part->temp_message_buffer, TRUE); GTK_OBJECT_CLASS (parent_class)->finalize (object); CAMEL_LOG_FULL_DEBUG ("Leaving CamelMimePart::finalize\n"); @@ -562,6 +569,31 @@ _set_content_object (CamelMedium *medium, CamelDataWrapper *content) } +static CamelDataWrapper * +_get_content_object (CamelMedium *medium) +{ + CamelMimePart *mime_part = CAMEL_MIME_PART (medium); + CamelStream *stream; + + /* + * test if there is not pending content stored in the + * temporary buffer + */ + if ((!medium->content ) || (mime_part->temp_message_buffer)) { + stream = camel_stream_mem_new_with_buffer (mime_part->temp_message_buffer, + CAMEL_STREAM_MEM_READ); + camel_mime_part_construct_content_from_stream (mime_part, stream); + /* + * Beware : this will destroy the temp buffer as well + */ + gtk_object_unref (GTK_OBJECT (stream)); + } + + return parent_class->get_content_object (medium); + +} + + /* **** */ @@ -725,10 +757,10 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimePart *mime_part = CAMEL_MIME_PART (data_wrapper); - + camel_mime_part_construct_headers_from_stream (mime_part, stream); - camel_mime_part_construct_content_from_stream (mime_part, stream); - + + camel_mime_part_store_stream_in_buffer (mime_part, stream); CAMEL_LOG_FULL_DEBUG ("CamelMimePart:: Leaving _construct_from_stream\n"); } diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index 8ea9cf5346..7d5b19c3aa 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -48,6 +48,7 @@ typedef struct { CamelMedium parent_object; + /* All fields here are -** PRIVATE **- */ gchar *description; GMimeContentField *disposition; gchar *content_id; @@ -57,6 +58,7 @@ typedef struct gchar *filename; GList *header_lines; + GByteArray *temp_message_buffer; GMimeContentField *content_type; } CamelMimePart; diff --git a/camel/camel-stream-mem.c b/camel/camel-stream-mem.c index 592caa5063..b659e4f30a 100644 --- a/camel/camel-stream-mem.c +++ b/camel/camel-stream-mem.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-ofmemet: 8 -*- */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-stream-mem.c : memory buffer based stream */ /* inspired by gnome-stream-mem.c in bonobo by Miguel de Icaza */ @@ -50,11 +50,11 @@ camel_stream_mem_class_init (CamelStreamMemClass *camel_stream_mem_class) { CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_stream_mem_class); GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_stream_mem_class); - + parent_class = gtk_type_class (gtk_object_get_type ()); /* virtual method definition */ - + /* virtual method overload */ camel_stream_class->read = _read; camel_stream_class->write = _write; @@ -63,16 +63,15 @@ camel_stream_mem_class_init (CamelStreamMemClass *camel_stream_mem_class) camel_stream_class->eos = _eos; camel_stream_class->close = _close; camel_stream_class->seek = _seek; - + gtk_object_class->finalize = _finalize; - + } static void camel_stream_mem_init (gpointer object, gpointer klass) { CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (object); - camel_stream_mem->buffer = g_byte_array_new (); camel_stream_mem->position = 0; } @@ -104,13 +103,29 @@ camel_stream_mem_get_type (void) CamelStream * camel_stream_mem_new (CamelStreamMemMode mode) { - CamelStreamMem *stream_mem; + CamelStreamMem *stream_mem; + GByteArray *buffer; - stream_mem = gtk_type_new (camel_stream_mem_get_type ()); - stream_mem->mode = mode; - return CAMEL_STREAM (stream_mem); + buffer = g_byte_array_new (); + stream_mem = (CamelStreamMem *)camel_stream_mem_new_with_buffer (buffer, mode); + return CAMEL_STREAM (stream_mem); } + +CamelStream * +camel_stream_mem_new_with_buffer (GByteArray *buffer, CamelStreamMemMode mode) +{ + CamelStreamMem *stream_mem; + + stream_mem = gtk_type_new (camel_stream_mem_get_type ()); + stream_mem->mode = mode; + stream_mem->buffer = buffer; + + return CAMEL_STREAM (stream_mem); +} + + + static void _finalize (GtkObject *object) { diff --git a/camel/camel-stream-mem.h b/camel/camel-stream-mem.h index dd30c89256..9878ec91c1 100644 --- a/camel/camel-stream-mem.h +++ b/camel/camel-stream-mem.h @@ -74,6 +74,11 @@ GtkType camel_stream_mem_get_type (void); /* public methods */ CamelStream *camel_stream_mem_new (CamelStreamMemMode mode); +CamelStream * camel_stream_mem_new_with_buffer (GByteArray *buffer, + CamelStreamMemMode mode); + + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/tests/test2.c b/tests/test2.c index 5b4e319c5d..20e8b739b9 100644 --- a/tests/test2.c +++ b/tests/test2.c @@ -30,7 +30,7 @@ main (int argc, char**argv) } camel_data_wrapper_construct_from_stream ( CAMEL_DATA_WRAPPER (message), input_stream); - + camel_medium_get_content_object (CAMEL_MEDIUM (message)); camel_stream_close (input_stream); gtk_object_unref (GTK_OBJECT (input_stream)); -- cgit