aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--camel/camel-mime-part-utils.c31
-rw-r--r--camel/camel-mime-part-utils.h2
-rw-r--r--camel/camel-mime-part.c44
-rw-r--r--camel/camel-mime-part.h2
-rw-r--r--camel/camel-stream-mem.c35
-rw-r--r--camel/camel-stream-mem.h5
-rw-r--r--tests/test2.c2
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 <Bertrand.Guiheneuf@aful.org>
+ * 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));