diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 118 | ||||
-rw-r--r-- | camel/Makefile.am | 2 | ||||
-rw-r--r-- | camel/camel-data-wrapper.c | 118 | ||||
-rw-r--r-- | camel/camel-data-wrapper.h | 21 | ||||
-rw-r--r-- | camel/camel-medium.c | 40 | ||||
-rw-r--r-- | camel/camel-medium.h | 23 | ||||
-rw-r--r-- | camel/camel-mime-message.c | 46 | ||||
-rw-r--r-- | camel/camel-mime-part-utils.c | 279 | ||||
-rw-r--r-- | camel/camel-mime-part-utils.h | 11 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 334 | ||||
-rw-r--r-- | camel/camel-mime-part.h | 12 | ||||
-rw-r--r-- | camel/camel-multipart.c | 161 | ||||
-rw-r--r-- | camel/camel-simple-data-wrapper-stream.c | 19 | ||||
-rw-r--r-- | camel/camel-simple-data-wrapper.c | 174 | ||||
-rw-r--r-- | camel/camel-simple-data-wrapper.h | 4 | ||||
-rw-r--r-- | camel/camel.c | 3 | ||||
-rw-r--r-- | camel/data-wrapper-repository.c | 133 | ||||
-rw-r--r-- | camel/data-wrapper-repository.h | 55 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 16 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-folder.c | 4 |
20 files changed, 441 insertions, 1132 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index e49dbb06e1..a7b0e30621 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,51 @@ +2000-04-24 NotZed <NotZed@HelixCode.com> + + * camel.c (camel_init): No longer call + data_wrapper_repository_init. + + * camel-medium.c (write_to_stream): Moved (back) to + camel-mime-part. + (add_header): + (set_header): + (remove_header): + (get_header): Make all these abstract, and spit warnings if + called. I guess it could manage the list, but well, it doesn't. + + * camel-medium.h (struct _CamelMedium): Dont store headers here, + the implementor is the only one who knows their format. + (CamelMediumClass): Changed header values to be void *'s. They + need not be strings? + + * camel-simple-data-wrapper.c (construct_from_stream): And we're + back. Set the output stream. + (construct_from_parser): Moved to camel-mime-part-utils. + + * camel-mime-part-utils.c + (camel_mime_part_construct_content_from_parser): Create the + contents of multipart and simple messages. + + * camel-multipart.c (construct_from_parser): Moved to + camel-mime-part-utils. + (separate_part): Removed. + + * camel-mime-part.c (construct_from_stream): Back again! This now + switches over to using a mime parser for any mime parts, only. + (my_write_to_stream): Write our headers and so forth here. + (add_header): Add header directly, parent class is abstract. + (remove_header): Ditto. + (set_header): Ditto. + + * camel-data-wrapper.c (camel_data_wrapper_construct_from_stream): + Remade abstract. + (camel_data_wrapper_construct_from_parser): Moved to + camel_mime_part. + + * camel-data-wrapper.h: Put back construct_from_stream. + + * camel-mime-part.h: Put construct_from_parser in here, the + data-wrapper shouldn't know about mime. Ok, so now to undo half + of the last hours changes ... duh. + 2000-04-23 Dan Winship <danw@helixcode.com> * camel-mime-utils.c (header_to_decode, header_mime_decode): fix @@ -5,8 +53,58 @@ 2000-04-23 NotZed <NotZed@HelixCode.com> + * providers/pop3/camel-pop3-folder.c (get_message_by_number): Use + construct_from_stream instead of set_input_stream(). + + * camel-simple-data-wrapper-stream.c + (camel_simple_data_wrapper_stream_construct): REmoved the destroy + callback code. + (wrapper_destroy_cb): Removed. + + * camel-simple-data-wrapper.h: Add prototype for _construct() + method. + + * camel.c: Include unicode.h to kill a warning. + + * camel-data-wrapper.h (CameldataWrapperClass): Removed + construct_from_stream virtual method. + Removed get/set input stream. + + * data-wrapper-repository.[ch]: Removed&from build. Obsoleted? + The justification as is follows: It is mixing storage + protocol/format with message architecture. It really just doesn't + serve any purpose, as each medium implementor will have to have its + own type->handler mapping, and the only current implementor, + mimepart has a very simple structure and no need for this. + + * camel-medium.c (write_to_stream): Moved here from most of the + stuff in camel-mime-part. Well, the MEDIUM is the one that knows + what the headers are, and the content is, let it write it out. + + * camel-mime-part-utils.c (camel_mime_part_construct_content): + Copied from camel-mime-part.c, removed handling of message + followon state (moved to camel-mime-message). + (camel_mime_part_construct_content_from_parser): Renamed from + construct_content. + (camel_mime_part_construct_headers_from_stream): + (camel_mime_part_construct_content_from_stream): + (camel_mime_part_store_stream_in_buffer): Removed. Replaced by + the new construct from parser stuff. + + * camel-mime-message.c (construct_from_parser): Do + construct_from_parser for mime-message. + (_write_to_stream): Set the mime-version header for medium to + write out, rather than writing it out ourselves. + * camel-data-wrapper.c (set_mime_type_field): Ref the content_field when we get it? + (construct_from_stream): Removed. + (camel_data_wrapper_construct_from_stream): Changed to a helper + function, creates a mime_parser, and constructs from that. + (set_input_stream): Removed. + (camel_data_wrapper_set_input_stream): Removed. + (get_input_stream): Removed. + (camel_data_wrapper_get_input_stream): Removed. * camel-mime-parser.c (camel_mime_parser_unstep): New function. Cause a subsequent call to mime_parser_step() to return the same @@ -14,19 +112,39 @@ * providers/mbox/camel-mbox-folder.c (_get_message_by_uid): Initial test code using the mime parser to construct the message. + (_get_message_by_uid): Use construct_from_stream() instead of + creating our own parser. * camel-mime-part.c (construct_from_parser): part constructor. (camel_mime_part_construct_content): Basically a simpler replacement for the datawrapper repository. (camel_mime_part_init): Set the default type to text/plain. + (camel_mime_part_construct_content): Removed to + camel-mime-part-utils.c + (my_get_output_stream): Removed. The streeam is in the + data-wrapper. + (my_get_content_object): Removed. The content object is stored in + the medium. If none is there, the object wasn't created properly. + (my_write_content_to_stream): Removed. The content object is the + one that knows how to write itself out!!!!!!!! + (my_write_to_stream): Remove the base header writing stuff - has + been moved to camel-medium, where it belongs. This can just be + used to check for mandatory headers. + (my_construct_from_stream): Removed. + (my_set_input_stream): What the hell, i'll remove this too. + Nobody seems to understand how it differs from create from stream, + and they both seem to serve the same purpose ... * camel-simple-data-wrapper.c (construct_from_parser): Initial implementation of a content constructor. + (construct_from_stream): Removed! Job taken over by + construct_from_parser. * camel-multipart.c (construct_from_parser): Multipart construction routine. (camel_multipart_init): Set the default multipart type to multipart/mixed. Duh, no subtype is not allowed anyway. + (set_input_stream): REmoved. Replaced by construct_from_parser. 2000-04-22 Dan Winship <danw@helixcode.com> diff --git a/camel/Makefile.am b/camel/Makefile.am index 5e8ea1e2d4..4fd033a315 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -62,7 +62,6 @@ libcamel_la_SOURCES = \ camel-stream-mem.c \ camel-transport.c \ camel-url.c \ - data-wrapper-repository.c \ gmime-content-field.c \ gmime-utils.c \ gstring-util.c \ @@ -110,7 +109,6 @@ libcamelinclude_HEADERS = \ camel-stream-mem.h \ camel-transport.h \ camel-url.h \ - data-wrapper-repository.h \ gmime-content-field.h \ gmime-utils.h \ gstring-util.h \ diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c index 1cff54a7c1..777d0361d9 100644 --- a/camel/camel-data-wrapper.c +++ b/camel/camel-data-wrapper.c @@ -6,8 +6,7 @@ /* * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> + * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -37,16 +36,11 @@ static GtkObjectClass *parent_class = NULL; #define CDW_CLASS(so) CAMEL_DATA_WRAPPER_CLASS (GTK_OBJECT (so)->klass) -static void set_input_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); -static CamelStream *get_input_stream (CamelDataWrapper *data_wrapper); static void set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static CamelStream *get_output_stream (CamelDataWrapper *data_wrapper); -static void construct_from_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); -static void construct_from_parser(CamelDataWrapper *, CamelMimeParser *); +static void construct_from_stream(CamelDataWrapper *, CamelStream *); static void write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static void set_mime_type (CamelDataWrapper *data_wrapper, @@ -67,18 +61,16 @@ camel_data_wrapper_class_init (CamelDataWrapperClass *camel_data_wrapper_class) /* virtual method definition */ camel_data_wrapper_class->write_to_stream = write_to_stream; - camel_data_wrapper_class->construct_from_stream = construct_from_stream; - camel_data_wrapper_class->construct_from_parser = construct_from_parser; camel_data_wrapper_class->set_mime_type = set_mime_type; 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; - camel_data_wrapper_class->set_input_stream = set_input_stream; - camel_data_wrapper_class->get_input_stream = get_input_stream; camel_data_wrapper_class->set_output_stream = set_output_stream; camel_data_wrapper_class->get_output_stream = get_output_stream; + camel_data_wrapper_class->construct_from_stream = construct_from_stream; + /* virtual method overload */ gtk_object_class->finalize = finalize; } @@ -135,71 +127,6 @@ finalize (GtkObject *object) parent_class->finalize (object); } - -static void -set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) -{ - if (data_wrapper->input_stream) - gtk_object_unref (GTK_OBJECT (data_wrapper->input_stream)); - - data_wrapper->input_stream = stream; - - if (!data_wrapper->output_stream && stream) - set_output_stream (data_wrapper, stream); - - if (stream) { - gtk_object_ref (GTK_OBJECT (stream)); - gtk_object_sink (GTK_OBJECT (stream)); - } -} - -/** - * camel_data_wrapper_set_input_stream: - * @data_wrapper: a data wrapper - * @stream: a stream that can be read from, or %NULL - * - * This sets the data wrapper's input stream from @stream, most likely - * causing @data_wrapper to initialize itself from that stream. - * @data_wrapper may or may not notice future changes to @stream, and - * if @stream is closed before @data_wrapper is destroyed, it could - * be arbitrarily bad. This function may fail, but there is no way - * for the caller to know this. - * - * If @data_wrapper has no output stream, its output stream will also - * be set to @stream. - **/ -void -camel_data_wrapper_set_input_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream) -{ - g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper)); - g_return_if_fail (stream == NULL || CAMEL_IS_STREAM (stream)); - - CDW_CLASS (data_wrapper)->set_input_stream (data_wrapper, stream); -} - - -static CamelStream * -get_input_stream (CamelDataWrapper *data_wrapper) -{ - return data_wrapper->input_stream; -} - -/** - * camel_data_wrapper_get_input_stream: - * @data_wrapper: a data wrapper - * - * Return value: @data_wrapper's input stream - **/ -CamelStream * -camel_data_wrapper_get_input_stream (CamelDataWrapper *data_wrapper) -{ - g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), NULL); - - return CDW_CLASS (data_wrapper)->get_input_stream (data_wrapper); -} - - static void set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { @@ -219,13 +146,13 @@ set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) * @data_wrapper: a data wrapper * @stream: a stream that can be read from * - * This sets the data wrapper's output stream to @stream. Unlike - * camel_data_wrapper_set_input_stream(), this function has no side - * effects. + * This is an internal function to be used by implementors of + * the camel-data-wrapper to set their contents as a stream. * * The output stream should theoretically be a stream that, if read * from, produces the data wrapper's contents. However, while certain * pieces of code assume this, nothing enforces it. + * **/ void camel_data_wrapper_set_output_stream (CamelDataWrapper *data_wrapper, @@ -249,6 +176,11 @@ get_output_stream (CamelDataWrapper *data_wrapper) * camel_data_wrapper_get_output_stream: * @data_wrapper: a data wrapper * + * If the data wrapper has contents, this will return a stream representing + * the data wrappers contents. Currently only the body of a simple + * mime part may be read in this way, although conceivably a whole + * mime message or partial mime message could be processed this way. + * * Return value: @data_wrapper's output stream **/ CamelStream * @@ -311,21 +243,20 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CDW_CLASS (data_wrapper)->write_to_stream (data_wrapper, stream); } - static void -construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +construct_from_stream(CamelDataWrapper *data_wrapper, + CamelStream *stream) { - /* nothing */ + g_warning("Construct from stream unimplemented for class: %s", gtk_type_name(((GtkObject *)data_wrapper)->klass->type)); } /** * camel_data_wrapper_construct_from_stream: * @data_wrapper: a data wrapper - * @stream: a stream that can be read from + * @stream: A stream that can be read from. * - * This constructs a data wrapper object from a stream. It is not clear - * how this differs from camel_data_wrapper_set_input_stream(), nor is - * it clear how it affects the data wrapper's input and output streams. + * Constructs the content of the data wrapper from the + * supplied @stream. * * This could fail, but you can't know if it did. **/ @@ -440,16 +371,3 @@ camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, CDW_CLASS (data_wrapper)->set_mime_type_field (data_wrapper, mime_type); } - -static void construct_from_parser(CamelDataWrapper *d, CamelMimeParser *mp) -{ - /* do nothing? */ - g_warning("Construct from parser not implemented for: %s", gtk_type_name(((GtkObject *)d)->klass->type)); -} - -void -camel_data_wrapper_construct_from_parser(CamelDataWrapper *data_wrapper, CamelMimeParser *mp) -{ - CDW_CLASS (data_wrapper)->construct_from_parser (data_wrapper, mp); -} - diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h index 0af3e73362..29e7be0f1e 100644 --- a/camel/camel-data-wrapper.h +++ b/camel/camel-data-wrapper.h @@ -37,7 +37,6 @@ extern "C" { #include <gtk/gtk.h> #include "camel-types.h" #include "gmime-content-field.h" -#include <camel/camel-mime-parser.h> #define CAMEL_DATA_WRAPPER_TYPE (camel_data_wrapper_get_type ()) #define CAMEL_DATA_WRAPPER(obj) (GTK_CHECK_CAST((obj), CAMEL_DATA_WRAPPER_TYPE, CamelDataWrapper)) @@ -62,9 +61,6 @@ typedef struct { GtkObjectClass parent_class; /* Virtual methods */ - void (*set_input_stream) (CamelDataWrapper *data_wrapper, - CamelStream *stream); - CamelStream * (*get_input_stream) (CamelDataWrapper *data_wrapper); void (*set_output_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream); CamelStream * (*get_output_stream) (CamelDataWrapper *data_wrapper); @@ -76,15 +72,11 @@ typedef struct { void (*set_mime_type_field) (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type_field); - - /* deprecated method */ void (*write_to_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream); - void (*construct_from_stream) (CamelDataWrapper *data_wrapper, - CamelStream *stream); - void (*construct_from_parser) (CamelDataWrapper *data_wrapper, - CamelMimeParser *); + void (*construct_from_stream) (CamelDataWrapper *data_wrapper, + CamelStream *); } CamelDataWrapperClass; @@ -105,19 +97,10 @@ GMimeContentField * camel_data_wrapper_get_mime_type_field (CamelDataWrappe void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type); -void camel_data_wrapper_set_input_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); -CamelStream * camel_data_wrapper_get_input_stream (CamelDataWrapper *data_wrapper); void camel_data_wrapper_set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); CamelStream * camel_data_wrapper_get_output_stream (CamelDataWrapper *data_wrapper); - -void camel_data_wrapper_construct_from_parser (CamelDataWrapper *data_wrapper, - CamelMimeParser *); - - -/* deprecated methods. Left until the new parser scheme is ok */ void camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); diff --git a/camel/camel-medium.c b/camel/camel-medium.c index fe87911b14..142d146ffe 100644 --- a/camel/camel-medium.c +++ b/camel/camel-medium.c @@ -1,7 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camelMedium.c : Abstract class for a medium */ -/* +/* camelMedium.c : Abstract class for a medium * * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> * Michael Zucchi <notzed@helixcode.com> @@ -24,14 +23,16 @@ * USA */ #include <config.h> -#include "camel-medium.h" #include <stdio.h> +#include <ctype.h> +#include "camel-medium.h" #include "gmime-content-field.h" #include "string-utils.h" #include "gmime-utils.h" #include "hash-table-utils.h" #include "camel-simple-data-wrapper.h" +#define d(x) static CamelDataWrapperClass *parent_class = NULL; @@ -39,15 +40,14 @@ static CamelDataWrapperClass *parent_class = NULL; #define CM_CLASS(so) CAMEL_MEDIUM_CLASS (GTK_OBJECT (so)->klass) static void add_header (CamelMedium *medium, const gchar *header_name, - const gchar *header_value); -static void set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value); + const void *header_value); +static void set_header (CamelMedium *medium, const gchar *header_name, const void *header_value); static void remove_header (CamelMedium *medium, const gchar *header_name); -static const gchar *get_header (CamelMedium *medium, const gchar *header_name); +static const void *get_header (CamelMedium *medium, const gchar *header_name); static CamelDataWrapper *get_content_object (CamelMedium *medium); static void set_content_object (CamelMedium *medium, CamelDataWrapper *content); - static void finalize (GtkObject *object); static void @@ -77,7 +77,6 @@ camel_medium_init (gpointer object, gpointer klass) { CamelMedium *camel_medium = CAMEL_MEDIUM (object); - camel_medium->headers = NULL; camel_medium->content = NULL; } @@ -111,8 +110,6 @@ finalize (GtkObject *object) { CamelMedium *medium = CAMEL_MEDIUM (object); - header_raw_clear(&medium->headers); - if (medium->content) gtk_object_unref (GTK_OBJECT (medium->content)); @@ -121,9 +118,9 @@ finalize (GtkObject *object) static void add_header (CamelMedium *medium, const gchar *header_name, - const gchar *header_value) + const void *header_value) { - header_raw_append(&medium->headers, header_name, header_value, -1); + g_warning("No %s::add_header implemented, adding %s", gtk_type_name(((GtkObject *)medium)->klass->type), header_name); } /** @@ -140,7 +137,7 @@ add_header (CamelMedium *medium, const gchar *header_name, **/ void camel_medium_add_header (CamelMedium *medium, const gchar *header_name, - const gchar *header_value) + const void *header_value) { g_return_if_fail (CAMEL_IS_MEDIUM (medium)); g_return_if_fail (header_name != NULL); @@ -150,9 +147,9 @@ camel_medium_add_header (CamelMedium *medium, const gchar *header_name, } static void -set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value) +set_header (CamelMedium *medium, const gchar *header_name, const void *header_value) { - header_raw_replace(&medium->headers, header_name, header_value, -1); + g_warning("No %s::set_header implemented, setting %s", gtk_type_name(((GtkObject *)medium)->klass->type), header_name); } /** @@ -165,7 +162,7 @@ set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_v * will be removed. **/ void -camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value) +camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const void *header_value) { g_return_if_fail (CAMEL_IS_MEDIUM (medium)); g_return_if_fail (header_name != NULL); @@ -177,7 +174,7 @@ camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const gc static void remove_header (CamelMedium *medium, const gchar *header_name) { - header_raw_remove(&medium->headers, header_name); + g_warning("No %s::remove_header implemented, removing %s", gtk_type_name(((GtkObject *)medium)->klass->type), header_name); } /** @@ -198,10 +195,11 @@ camel_medium_remove_header (CamelMedium *medium, const gchar *header_name) } -static const gchar * +static const void * get_header (CamelMedium *medium, const gchar *header_name) { - return header_raw_find(&medium->headers, header_name, NULL); + g_warning("No %s::get_header implemented, getting %s", gtk_type_name(((GtkObject *)medium)->klass->type), header_name); + return NULL; } /** @@ -216,12 +214,14 @@ get_header (CamelMedium *medium, const gchar *header_name) * * Return value: the value of the named header, or %NULL **/ -const gchar * +const void * camel_medium_get_header (CamelMedium *medium, const gchar *header_name) { g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL); g_return_val_if_fail (header_name != NULL, NULL); +#warning No way to get multi-valued headers? + return CM_CLASS (medium)->get_header (medium, header_name); } diff --git a/camel/camel-medium.h b/camel/camel-medium.h index 91693439e2..6971117382 100644 --- a/camel/camel-medium.h +++ b/camel/camel-medium.h @@ -37,7 +37,6 @@ extern "C" { #include <gtk/gtk.h> #include <camel/camel-types.h> #include <camel/camel-data-wrapper.h> -#include <camel/camel-mime-utils.h> #define CAMEL_MEDIUM_TYPE (camel_medium_get_type ()) #define CAMEL_MEDIUM(obj) (GTK_CHECK_CAST((obj), CAMEL_MEDIUM_TYPE, CamelMedium)) @@ -49,8 +48,6 @@ struct _CamelMedium { CamelDataWrapper parent_object; - struct _header_raw *headers; - /* The content of the medium, as opposed to our parent * CamelDataWrapper, which wraps both the headers and the * content. @@ -65,34 +62,30 @@ typedef struct { CamelDataWrapperClass parent_class; /* Virtual methods */ - void (*add_header) (CamelMedium *medium, const gchar *header_name, const gchar *header_value); - void (*set_header) (CamelMedium *medium, const gchar *header_name, const gchar *header_value); + void (*add_header) (CamelMedium *medium, const gchar *header_name, const void *header_value); + void (*set_header) (CamelMedium *medium, const gchar *header_name, const void *header_value); void (*remove_header) (CamelMedium *medium, const gchar *header_name); - const gchar * (*get_header) (CamelMedium *medium, const gchar *header_name); + const void * (*get_header) (CamelMedium *medium, const gchar *header_name); CamelDataWrapper * (*get_content_object) (CamelMedium *medium); void (*set_content_object) (CamelMedium *medium, CamelDataWrapper *content); } CamelMediumClass; - - /* Standard Gtk function */ GtkType camel_medium_get_type (void); - -/* public methods */ -void camel_medium_add_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value); -void camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const gchar *header_value); +/* Header get/set interface */ +void camel_medium_add_header (CamelMedium *medium, const gchar *header_name, const void *header_value); +void camel_medium_set_header (CamelMedium *medium, const gchar *header_name, const void *header_value); void camel_medium_remove_header (CamelMedium *medium, const gchar *header_name); -const gchar *camel_medium_get_header (CamelMedium *medium, const gchar *header_name); - +const void *camel_medium_get_header (CamelMedium *medium, const gchar *header_name); +/* accessor methods */ CamelDataWrapper *camel_medium_get_content_object (CamelMedium *medium); void camel_medium_set_content_object (CamelMedium *medium, CamelDataWrapper *content); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index 6561515ec3..f63548e5a5 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -31,6 +31,8 @@ #include "gmime-utils.h" #include "hash-table-utils.h" +#define d(x) + typedef enum { HEADER_UNKNOWN, HEADER_FROM, @@ -63,9 +65,10 @@ static void _set_message_number (CamelMimeMessage *mime_message, guint number); static guint _get_message_number (CamelMimeMessage *mime_message); static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static void _finalize (GtkObject *object); -static void add_header (CamelMedium *medium, const char *header_name, const char *header_value); -static void set_header (CamelMedium *medium, const char *header_name, const char *header_value); +static void add_header (CamelMedium *medium, const char *header_name, const void *header_value); +static void set_header (CamelMedium *medium, const char *header_name, const void *header_value); static void remove_header (CamelMedium *medium, const char *header_name); +static void construct_from_parser (CamelMimePart *, CamelMimeParser *); /* Returns the class for a CamelMimeMessage */ #define CMM_CLASS(so) CAMEL_MIME_MESSAGE_CLASS (GTK_OBJECT(so)->klass) @@ -90,7 +93,7 @@ static void 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);*/ + CamelMimePartClass *camel_mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_class); GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_mime_message_class); CamelMediumClass *camel_medium_class = CAMEL_MEDIUM_CLASS (camel_mime_message_class); @@ -120,6 +123,8 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) camel_medium_class->set_header = set_header; camel_medium_class->remove_header = remove_header; + camel_mime_part_class->construct_from_parser = construct_from_parser; + gtk_object_class->finalize = _finalize; } @@ -474,8 +479,24 @@ camel_mime_message_get_message_number (CamelMimeMessage *mime_message) return CMM_CLASS (mime_message)->get_message_number (mime_message); } +/* mime_message */ +static void +construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp) +{ + char *buf; + int len; + d(printf("constructing mime-message\n")); + /* let the mime-part construct the guts ... */ + ((CamelMimePartClass *)parent_class)->construct_from_parser(dw, mp); + + /* ... then clean up the follow-on state */ + if (camel_mime_parser_step(mp, &buf, &len) != HSCAN_MESSAGE_END) { + g_warning("Bad parser state: Expecing MESSAGE_END, got: %d", camel_mime_parser_state(mp)); + camel_mime_parser_unstep(mp); + } +} #ifdef WHPT #warning : WHPT is already defined !!!!!! @@ -506,14 +527,6 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimeMessage *mm = CAMEL_MIME_MESSAGE (data_wrapper); -#if 0 -#warning each header should be stored in the raw headers - WHPT (stream, "From", mm->from); - WHPT (stream, "Reply-To", mm->reply_to); - WHPT (stream, "Date", mm->received_date); - WHPT (stream, "Subject", mm->subject); -#endif - /* force mandatory headers ... */ if (mm->from == NULL) { g_warning("No from set for message"); @@ -528,16 +541,15 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) camel_mime_message_set_subject(mm, "No Subject"); } + camel_medium_set_header((CamelMedium *)mm, "Mime-Version", "1.0"); + +#if 1 #warning need to store receipients lists to headers -#if 0 /* FIXME: remove this snot ... */ _write_recipients_to_stream (mm, stream); #endif - /* FIXME correct to do it here? */ - WHPT (stream, "Mime-Version", "1.0"); CAMEL_DATA_WRAPPER_CLASS (parent_class)->write_to_stream (data_wrapper, stream); - } /*******************************/ @@ -613,14 +625,14 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ } static void -set_header(CamelMedium *medium, const char *header_name, const char *header_value) +set_header(CamelMedium *medium, const char *header_name, const void *header_value) { process_header(medium, header_name, header_value); parent_class->parent_class.set_header (medium, header_name, header_value); } static void -add_header(CamelMedium *medium, const char *header_name, const char *header_value) +add_header(CamelMedium *medium, const char *header_name, const void *header_value) { /* if we process it, then it must be forced unique as well ... */ if (process_header(medium, header_name, header_value)) diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index a4392d5f88..460a6c7d03 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -1,11 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-mime-part-utils : Utility for mime parsing and so on */ - - -/* +/* camel-mime-part-utils : Utility for mime parsing and so on * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> + * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> + * Michael Zucchi <notzed@helixcode.com> * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -25,141 +22,189 @@ * USA */ #include <config.h> +#include <string.h> #include "gmime-content-field.h" #include "string-utils.h" #include "gmime-utils.h" #include "camel-simple-data-wrapper.h" -#include "data-wrapper-repository.h" #include "camel-mime-part-utils.h" +#include "camel-mime-message.h" +#include "camel-multipart.h" +#include "camel-mime-body-part.h" +#include "camel-seekable-substream.h" +#include "camel-stream-filter.h" +#include "camel-stream-mem.h" +#include "camel-mime-filter-basic.h" +#include "camel-mime-filter-charset.h" -/* declare this function because it is public - but it must not be called except here */ -void camel_mime_part_set_content_type (CamelMimePart *mime_part, - gchar *content_type); - +#define d(x) -void -camel_mime_part_construct_headers_from_stream (CamelMimePart *mime_part, - CamelStream *stream) +/* simple data wrapper */ +static void +simple_data_wrapper_construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp) { - GArray *header_array; - Rfc822Header *cur_header; - int i; - - g_assert (stream); - /* - * parse all header lines - */ - header_array = get_header_array_from_stream (stream); - if (header_array) { - for (i=0; i<header_array->len; i++) { - cur_header = (Rfc822Header *)header_array->data + i; - camel_medium_add_header ( CAMEL_MEDIUM (mime_part), - cur_header->name, - cur_header->value); - g_free (cur_header->name); - g_free (cur_header->value); + GByteArray *buffer; + char *buf; + int len; + off_t start, end; + CamelMimeFilter *fdec = NULL, *fch = NULL; + struct _header_content_type *ct; + int decid=-1, chrid=-1, cache=FALSE; + CamelStream *source; + char *encoding; + + d(printf("constructing simple-data-wrapper\n")); + + /* Ok, try and be smart. If we're storing a small message (typical) convert it, + and store it in memory as we parse it ... if not, throw away the conversion + and scan till the end ... */ + + /* if we can't seek, dont have a stream/etc, then we must cache it */ + source = camel_mime_parser_stream(mp); + gtk_object_ref((GtkObject *)source); + if (source == NULL + || !CAMEL_IS_SEEKABLE_STREAM(source)) + cache = TRUE; + + /* first, work out conversion, if any, required, we dont care about what we dont know about */ + encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL)); + if (encoding) { + if (!strcasecmp(encoding, "base64")) { + d(printf("Adding base64 decoder ...\n")); + fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC); + decid = camel_mime_parser_filter_add(mp, fdec); + } else if (!strcasecmp(encoding, "quoted-printable")) { + d(printf("Adding quoted-printable decoder ...\n")); + fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC); + decid = camel_mime_parser_filter_add(mp, fdec); } + g_free(encoding); + } - g_array_free (header_array, TRUE); + /* if we're doing text, then see if we have to convert it to UTF8 as well */ + ct = camel_mime_parser_content_type(mp); + if (header_content_type_is(ct, "text", "*")) { + const char *charset = header_content_type_param(ct, "charset"); + if (charset!=NULL + && !(strcasecmp(charset, "us-ascii")==0 + || strcasecmp(charset, "utf-8")==0)) { + d(printf("Adding conversion filter from %s to utf-8\n", charset)); + fch = (CamelMimeFilter *)camel_mime_filter_charset_new_convert(charset, "utf-8"); + if (fch) { + chrid = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)fch); + } else { + g_warning("Cannot convert '%s' to 'utf-8', message display may be corrupt", charset); + } + } } -} + buffer = g_byte_array_new(); + + /* write to a memory buffer or something??? */ + start = camel_mime_parser_tell(mp); + while ( camel_mime_parser_step(mp, &buf, &len) != HSCAN_BODY_END ) { + if (buffer) { + if (buffer->len > 20480 && !cache) { + /* is this a 'big' message? Yes? We dont want to convert it all then.*/ + camel_mime_parser_filter_remove(mp, decid); + camel_mime_parser_filter_remove(mp, chrid); + decid = -1; + chrid = -1; + g_byte_array_free(buffer, TRUE); + buffer = NULL; + } else { + g_byte_array_append(buffer, buf, len); + } + } + } + if (buffer) { + CamelStream *mem; + d(printf("Small message part, kept in memory!\n")); + mem = camel_stream_mem_new_with_byte_array(buffer, CAMEL_STREAM_MEM_READ); + camel_data_wrapper_set_output_stream (dw, mem); + } else { + CamelSeekableSubstream *sub; + CamelStreamFilter *filter; + + d(printf("Big message part, left on disk ...\n")); + + end = camel_mime_parser_tell(mp); + sub = (CamelSeekableSubstream *)camel_seekable_substream_new_with_seekable_stream_and_bounds ((CamelSeekableStream *)source, start, end); + if (fdec || fch) { + filter = camel_stream_filter_new_with_stream((CamelStream *)sub); + if (fdec) { + camel_mime_filter_reset(fdec); + camel_stream_filter_add(filter, fdec); + } + if (fch) { + camel_mime_filter_reset(fdec); + camel_stream_filter_add(filter, fch); + } + camel_data_wrapper_set_output_stream (dw, (CamelStream *)filter); + } else { + camel_data_wrapper_set_output_stream (dw, (CamelStream *)sub); + } + } + camel_mime_parser_filter_remove(mp, decid); + camel_mime_parser_filter_remove(mp, chrid); + if (fdec) + gtk_object_unref((GtkObject *)fdec); + if (fch) + gtk_object_unref((GtkObject *)fch); + gtk_object_unref((GtkObject *)source); -void -camel_mime_part_construct_content_from_stream (CamelMimePart *mime_part, - CamelStream *stream) -{ - GMimeContentField *content_type = NULL; - gchar *mime_type = NULL; - GtkType content_object_type; - CamelDataWrapper *content_object = NULL; - - - /* - * find content mime type - */ - content_type = camel_mime_part_get_content_type (mime_part); - /* here we should have a mime type */ - if (content_type) - mime_type = gmime_content_field_get_mime_type (content_type); - - /* - * no mime type found for the content, - * using text/plain is the default - */ - if (!mime_type) { - mime_type = g_strdup ("text/plain"); - camel_mime_part_set_content_type (mime_part, mime_type); - } - - /* - * find in the repository what particular data wrapper is - * associated to this mime type - */ - content_object_type = - data_wrapper_repository_get_data_wrapper_type (mime_type); - - g_free (mime_type); - - /* - * create the content object data wrapper with the type - * returned by the data wrapper repository - */ - 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_medium_set_content_object ( CAMEL_MEDIUM (mime_part), content_object); - - /* set the input stream for the content object */ - camel_data_wrapper_set_input_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)); } - - +/* This replaces the data wrapper repository ... and/or could be replaced by it? */ void -camel_mime_part_store_stream_in_buffer (CamelMimePart *mime_part, - CamelStream *stream) +camel_mime_part_construct_content_from_parser(CamelMimePart *dw, CamelMimeParser *mp) { - 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); - - if (nb_bytes_read_chunk>0) { - nb_bytes_read_total += nb_bytes_read_chunk; - - while (nb_bytes_read_chunk >0) { - 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; + CamelDataWrapper *content = NULL; + char *buf; + int len; + + switch (camel_mime_parser_state(mp)) { + case HSCAN_HEADER: + d(printf("Creating body part\n")); + content = (CamelDataWrapper *)camel_simple_data_wrapper_new(); + break; + case HSCAN_MESSAGE: + d(printf("Creating message part\n")); + content = (CamelDataWrapper *)camel_mime_message_new(); + simple_data_wrapper_construct_from_parser(content, mp); + break; + case HSCAN_MULTIPART: { + CamelDataWrapper *bodypart; + +#warning This should use a camel-mime-multipart + d(printf("Creating multi-part\n")); + content = (CamelDataWrapper *)camel_multipart_new(); + + /* get/set boundary? */ + + while (camel_mime_parser_step(mp, &buf, &len) != HSCAN_MULTIPART_END) { + camel_mime_parser_unstep(mp); + bodypart = (CamelDataWrapper *)camel_mime_body_part_new(); + camel_mime_part_construct_from_parser((CamelMimePart *)bodypart, mp); + camel_multipart_add_part((CamelMultipart *)dw, (CamelMimeBodyPart *)bodypart); } + break; } + default: + g_warning("Invalid state encountered???: %d", camel_mime_parser_state(mp)); + } + if (content) { +#warning there just has got to be a better way ... to transfer the mime-type to the datawrapper + /* would you believe you have to set this BEFORE you set the content object??? oh my god !!!! */ + camel_data_wrapper_set_mime_type_field (content, + camel_mime_part_get_content_type ((CamelMimePart *)dw)); + camel_medium_set_content_object((CamelMedium *)dw, content); } - - 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 85e86a25e9..a4e58ec2a2 100644 --- a/camel/camel-mime-part-utils.h +++ b/camel/camel-mime-part-utils.h @@ -35,16 +35,7 @@ extern "C" { #include "camel-mime-part.h" - -void camel_mime_part_construct_headers_from_stream (CamelMimePart *mime_part, - CamelStream *stream); - -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); - +void camel_mime_part_construct_content_from_parser(CamelMimePart *, CamelMimeParser *mp); #ifdef __cplusplus } diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 78f1897e8b..d84d560eff 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -32,20 +32,10 @@ #include "gmime-utils.h" #include "camel-simple-data-wrapper.h" #include "hash-table-utils.h" -#include "camel-stream-mem.h" #include "camel-mime-part-utils.h" -#include "camel-seekable-substream.h" -#include "camel-stream-filter.h" -#include "camel-mime-filter-basic.h" -#include "camel-mime-filter-charset.h" #include <ctype.h> #include "camel-mime-parser.h" -/* ick, this shouldn't need to know about the parent types ... then again the repository does *sigh* */ -#include "camel-mime-message.h" -#include "camel-multipart.h" -#include "camel-mime-body-part.h" - #define d(x) typedef enum { @@ -76,22 +66,18 @@ static void my_finalize (GtkObject *object); /* from CamelDataWrapper */ static void my_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); -static void my_construct_from_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); -static void construct_from_parser (CamelDataWrapper *, CamelMimeParser *); -static void my_set_input_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); -static CamelStream * my_get_output_stream (CamelDataWrapper *data_wrapper); - +static void construct_from_stream (CamelDataWrapper *dw, CamelStream *s); /* from CamelMedia */ -static void add_header (CamelMedium *medium, const char *header_name, const char *header_value); -static void set_header (CamelMedium *medium, const char *header_name, const char *header_value); +static void add_header (CamelMedium *medium, const char *header_name, const void *header_value); +static void set_header (CamelMedium *medium, const char *header_name, const void *header_value); static void remove_header (CamelMedium *medium, const char *header_name); +static const void *get_header (CamelMedium *medium, const char *header_name); -static void my_set_content_object (CamelMedium *medium, - CamelDataWrapper *content); -static CamelDataWrapper *my_get_content_object (CamelMedium *medium); +static void my_set_content_object (CamelMedium *medium, CamelDataWrapper *content); + +/* from camel mime parser */ +static void construct_from_parser (CamelMimePart *, CamelMimeParser *); /* forward references */ static void set_disposition (CamelMimePart *mime_part, const gchar *disposition); @@ -122,19 +108,18 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) parent_class = gtk_type_class (camel_medium_get_type ()); my_init_header_name_table(); + + camel_mime_part_class->construct_from_parser = construct_from_parser; /* virtual method overload */ camel_medium_class->add_header = add_header; camel_medium_class->set_header = set_header; + camel_medium_class->get_header = get_header; camel_medium_class->remove_header = remove_header; camel_medium_class->set_content_object = my_set_content_object; - camel_medium_class->get_content_object = my_get_content_object; camel_data_wrapper_class->write_to_stream = my_write_to_stream; - camel_data_wrapper_class->construct_from_stream = my_construct_from_stream; - camel_data_wrapper_class->construct_from_parser = construct_from_parser; - camel_data_wrapper_class->set_input_stream = my_set_input_stream; -/* camel_data_wrapper_class->get_output_stream = my_get_output_stream;*/ + camel_data_wrapper_class->construct_from_stream= construct_from_stream; gtk_object_class->finalize = my_finalize; } @@ -253,15 +238,19 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ static void -set_header (CamelMedium *medium, const char *header_name, const char *header_value) +set_header (CamelMedium *medium, const char *header_name, const void *header_value) { + CamelMimePart *part = (CamelMimePart *)medium; + process_header(medium, header_name, header_value); - parent_class->set_header (medium, header_name, header_value); + header_raw_replace(&part->headers, header_name, header_value, -1); } static void -add_header (CamelMedium *medium, const char *header_name, const char *header_value) +add_header (CamelMedium *medium, const char *header_name, const void *header_value) { + CamelMimePart *part = (CamelMimePart *)medium; + /* Try to parse the header pair. If it corresponds to something */ /* known, the job is done in the parsing routine. If not, */ /* we simply add the header in a raw fashion */ @@ -270,16 +259,26 @@ add_header (CamelMedium *medium, const char *header_name, const char *header_val /* If it was one of the headers we handled, it must be unique, set it instead of add */ if (process_header(medium, header_name, header_value)) - parent_class->set_header (medium, header_name, header_value); + header_raw_replace(&part->headers, header_name, header_value, -1); else - parent_class->add_header (medium, header_name, header_value); + header_raw_append(&part->headers, header_name, header_value, -1); } static void remove_header (CamelMedium *medium, const char *header_name) { + CamelMimePart *part = (CamelMimePart *)medium; + process_header(medium, header_name, NULL); - parent_class->remove_header (medium, header_name); + header_raw_remove(&part->headers, header_name); +} + +static const void * +get_header (CamelMedium *medium, const char *header_name) +{ + CamelMimePart *part = (CamelMimePart *)medium; + + return header_raw_find(&part->headers, header_name, NULL); } @@ -501,53 +500,6 @@ my_set_content_object (CamelMedium *medium, CamelDataWrapper *content) gmime_content_field_ref (object_content_field); } -static CamelDataWrapper * -my_get_content_object (CamelMedium *medium) -{ - CamelMimePart *mime_part = CAMEL_MIME_PART (medium); - CamelStream *stream; - CamelStream *decoded_stream; - CamelMimeFilter *mf = NULL; - - d(printf("getting content object? for %p\n", medium)); - - if (!medium->content ) { - stream = mime_part->content_input_stream; - decoded_stream = stream; - - g_warning("No content object, this old code is probably going to crash ..."); - - switch (mime_part->encoding) { - case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE: - mf = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC); - break; - case CAMEL_MIME_PART_ENCODING_BASE64: - mf = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC); - break; - default: - break; - } - - if (mf) { - decoded_stream = (CamelStream *)camel_stream_filter_new_with_stream (stream); - camel_stream_filter_add((CamelStreamFilter *)decoded_stream, mf); - gtk_object_unref((GtkObject *)mf); - } - - camel_mime_part_construct_content_from_stream (mime_part, decoded_stream); - - } - - return parent_class->get_content_object (medium); - -} - - -/* **** */ - - - - /**********************************************************************/ #ifdef WHPT #warning : WHPT is already defined !!!!!! @@ -556,163 +508,39 @@ my_get_content_object (CamelMedium *medium) static void -my_write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream) -{ - CamelMedium *medium; - CamelStream *wrapper_stream; - CamelStream *stream_encode; - CamelMimeFilter *mf = NULL; - CamelDataWrapper *content; - - g_assert (mime_part); - - medium = CAMEL_MEDIUM (mime_part); - content = medium->content; - - if (!content) { - content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - if (!content) - return; - } - - switch (mime_part->encoding) { - case CAMEL_MIME_PART_ENCODING_DEFAULT: - case CAMEL_MIME_PART_ENCODING_7BIT: - case CAMEL_MIME_PART_ENCODING_8BIT: - camel_data_wrapper_write_to_stream (content, stream); - break; - case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE: - mf = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_ENC); - break; - case CAMEL_MIME_PART_ENCODING_BASE64: - mf = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_ENC); - break; - default: - camel_data_wrapper_write_to_stream (content, stream); - g_warning ("Encoding type `%s' not supported.", - camel_mime_part_encoding_to_string - (mime_part->encoding)); - } - - if (mf) { - /* encode the data wrapper output stream in the filtered encoding */ - wrapper_stream = camel_data_wrapper_get_output_stream (content); - camel_stream_reset (wrapper_stream); - stream_encode = (CamelStream *)camel_stream_filter_new_with_stream (wrapper_stream); - camel_stream_filter_add((CamelStreamFilter *)stream_encode, mf); - - /* ... and write it to the output stream in a blocking way */ - camel_stream_write_to_stream (stream_encode, stream); - - /* now free the intermediate b64 stream */ - gtk_object_unref (GTK_OBJECT (stream_encode)); - gtk_object_unref((GtkObject *)mf); - } -} - - - - -/* FIXME: this is just totally broken broken broken broken */ - -static void my_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimePart *mp = CAMEL_MIME_PART (data_wrapper); CamelMedium *medium = CAMEL_MEDIUM (data_wrapper); + CamelDataWrapper *content; d(printf("mime_part::write_to_stream\n")); -#warning This class should NOT BE WRITING the headers out - if (medium->headers) { - struct _header_raw *h = medium->headers; + /* FIXME: something needs to be done about this ... */ +#warning content-languages should be stored as a header + gmime_write_header_with_glist_to_stream (stream, "Content-Language", mp->content_languages,", "); + + if (mp->headers) { + struct _header_raw *h = mp->headers; while (h) { camel_stream_write_strings (stream, h->name, isspace(h->value[0])?":":": ", h->value, "\n", NULL); h = h->next; } } - /* FIXME: something needs to be done about this ... */ - gmime_write_header_with_glist_to_stream (stream, "Content-Language", mp->content_languages,", "); - camel_stream_write_string(stream,"\n"); -#if 1 - { - CamelDataWrapper *content = camel_medium_get_content_object (CAMEL_MEDIUM (data_wrapper)); - if (content) { - camel_data_wrapper_write_to_stream(content, stream); - } else { - g_warning("No content for data wrapper"); - } - } -#else - ((CamelDataWrapperClass *)parent_class)->write_to_stream (data_wrapper, stream); -#endif - /*my_write_content_to_stream (mp, stream);*/ -} - - - -static void -my_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_store_stream_in_buffer (mime_part, stream); -} - - -/* FIXME: this should be in another file ... */ -/* This replaces the data wrapper repository ... and/or could be replaced by it? */ -static void -camel_mime_part_construct_content(CamelDataWrapper *dw, CamelMimeParser *mp) -{ - CamelDataWrapper *content = NULL; - int state; - - switch ((state = camel_mime_parser_state(mp))) { - case HSCAN_HEADER: - d(printf("Creating body part\n")); - content = (CamelDataWrapper *)camel_simple_data_wrapper_new(); - break; - case HSCAN_MESSAGE: - d(printf("Creating message part\n")); - content = (CamelDataWrapper *)camel_mime_message_new(); - break; - case HSCAN_MULTIPART: - d(printf("Creating multi-part\n")); - content = (CamelDataWrapper *)camel_multipart_new(); - break; - default: - g_warning("Invalid state encountered???: %d", camel_mime_parser_state(mp)); - } + content = camel_medium_get_content_object (medium); if (content) { - camel_data_wrapper_construct_from_parser(content, mp); -#warning there just has got to be a better way ... to transfer the mime-type to the datawrapper - /* would you believe you have to set this BEFORE you set the content object??? oh my god !!!! */ - camel_data_wrapper_set_mime_type_field (content, - camel_mime_part_get_content_type ((CamelMimePart *)dw)); - camel_medium_set_content_object((CamelMedium *)dw, content); - } - /* this should probably go into camel-mime-message::construct_from_parser */ - if (state == HSCAN_MESSAGE) { - char *buf; - int len; - - if (camel_mime_parser_step(mp, &buf, &len) != HSCAN_MESSAGE_END) { - g_warning("Bad parser state: Expecing MESSAGE_EOF, got: %d", camel_mime_parser_state(mp)); - camel_mime_parser_unstep(mp); - } + camel_data_wrapper_write_to_stream(content, stream); + } else { + g_warning("No content for medium, nothing to write"); } } /* mime_part */ static void -construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp) +construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp) { struct _header_raw *headers; char *buf; @@ -730,79 +558,31 @@ construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp) camel_medium_add_header((CamelMedium *)dw, headers->name, headers->value); headers = headers->next; } - camel_mime_part_construct_content(dw, mp); + camel_mime_part_construct_content_from_parser(dw, mp); break; default: g_warning("Invalid state encountered???: %d", camel_mime_parser_state(mp)); } } -static void -my_set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +void +camel_mime_part_construct_from_parser(CamelMimePart *mime_part, CamelMimeParser *mp) { - CamelMimePart *mime_part = CAMEL_MIME_PART (data_wrapper); - CamelSeekableStream *seekable_stream; - guint32 content_stream_inf_bound; - - - g_assert (CAMEL_IS_SEEKABLE_STREAM (stream)); - seekable_stream = CAMEL_SEEKABLE_STREAM (stream); - - /* call parent class implementation */ - CAMEL_DATA_WRAPPER_CLASS (parent_class)->set_input_stream (data_wrapper, stream); - - - camel_mime_part_construct_headers_from_stream (mime_part, stream); - - /* set the input stream for the content object */ - content_stream_inf_bound = camel_seekable_stream_get_current_position (seekable_stream); - - if (mime_part->content_input_stream) - gtk_object_unref (GTK_OBJECT (mime_part->content_input_stream)); - mime_part->content_input_stream = camel_seekable_substream_new_with_seekable_stream_and_bounds (seekable_stream, - content_stream_inf_bound, - -1); - gtk_object_ref (GTK_OBJECT (mime_part->content_input_stream)); - gtk_object_sink (GTK_OBJECT (mime_part->content_input_stream)); + CMP_CLASS (mime_part)->construct_from_parser (mime_part, mp); } - -static CamelStream * -my_get_output_stream (CamelDataWrapper *data_wrapper) +static void +construct_from_stream(CamelDataWrapper *dw, CamelStream *s) { - CamelMimePart *mime_part = CAMEL_MIME_PART (data_wrapper); - CamelStream *input_stream; - CamelStream *output_stream; - /* ** FIXME : bogus bogus bogus - test test test */ - - return NULL; - - /* - * For the moment, we do not use this routine on - * mime parts. Maybe later. - */ - input_stream = camel_data_wrapper_get_input_stream (data_wrapper); - - if (input_stream == NULL) - return NULL; + CamelMimeParser *mp; - switch (mime_part->encoding) { - - case CAMEL_MIME_PART_ENCODING_DEFAULT: - case CAMEL_MIME_PART_ENCODING_7BIT: - case CAMEL_MIME_PART_ENCODING_8BIT: - return input_stream; - - case CAMEL_MIME_PART_ENCODING_BASE64: - return output_stream; - - case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE: - return input_stream; - default: - break; + mp = camel_mime_parser_new(); + if (camel_mime_parser_init_with_stream(mp, s) == -1) { + g_warning("Cannot create parser for stream"); + } else { + camel_mime_part_construct_from_parser((CamelMimePart *)dw, mp); } - - return NULL; + gtk_object_unref((GtkObject *)mp); } diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index 89409dab5f..eb8d2b278e 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -3,8 +3,8 @@ /* * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> + * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> + * Michael Zucchi <notzed@helixcode.com> * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -38,6 +38,7 @@ extern "C" { #include "camel-types.h" #include "camel-medium.h" #include <camel/camel-mime-utils.h> +#include <camel/camel-mime-parser.h> #define CAMEL_MIME_PART_TYPE (camel_mime_part_get_type ()) #define CAMEL_MIME_PART(obj) (GTK_CHECK_CAST((obj), CAMEL_MIME_PART_TYPE, CamelMimePart)) @@ -73,7 +74,8 @@ struct _CamelMimePart GByteArray *temp_message_buffer; GMimeContentField *content_type; CamelStream *content_input_stream; - + + struct _header_raw *headers; /* mime headers */ }; @@ -82,6 +84,7 @@ typedef struct { CamelMediumClass parent_class; /* Virtual methods */ + void (*construct_from_parser) (CamelMimePart *, CamelMimeParser *); } CamelMimePartClass; @@ -119,6 +122,9 @@ GMimeContentField *camel_mime_part_get_content_type (CamelMimePart *mime_part); const gchar * camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding); CamelMimePartEncodingType camel_mime_part_encoding_from_string (const gchar *string); +/* construction */ +void camel_mime_part_construct_from_parser (CamelMimePart *, CamelMimeParser *); + /* utility functions */ void camel_mime_part_set_text (CamelMimePart *camel_mime_part, const gchar *text); diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c index 94ec8a4dbf..1ebeed4f8f 100644 --- a/camel/camel-multipart.c +++ b/camel/camel-multipart.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-multipart.c : Abstract class for a multipart */ +#warning This should be a mostly abstract class, but it is not! /* * @@ -55,11 +56,7 @@ static void set_boundary (CamelMultipart *multipart, static const gchar * get_boundary (CamelMultipart *multipart); static void write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); -static void set_input_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); static void finalize (GtkObject *object); -static void construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp); - static CamelDataWrapperClass *parent_class = NULL; @@ -96,9 +93,6 @@ 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->set_input_stream = set_input_stream; - - camel_data_wrapper_class->construct_from_parser = construct_from_parser; gtk_object_class->finalize = finalize; } @@ -523,156 +517,3 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) if (multipart->postface) camel_stream_write_strings (stream, multipart->postface, NULL); } - - -/** - * separate_part: separate one part in a multipart environement. - * @stream: the stream to read the lines from. - * @normal_boundary: end of part bundary. - * @end_boundary: end of multipart boundary. - * @end_position: end position of the mime part - * - * This routine is a bit special: RFC 2046 says that, in a multipart - * environment, the last CRLF before a boundary belongs to the boundary. - * Thus, if there is no blank line before the boundary, the last CRLF - * of the last line of the part is removed. - * - * Return value: %TRUE if the last boundary element has been found or - * if no more data was available from the stream, %FALSE otherwise - **/ -static gboolean -separate_part (CamelStream *stream, gchar *normal_boundary, - gchar *end_boundary, guint32 *end_position) -{ - gchar *new_line = NULL; - gboolean end_of_part = FALSE; - gboolean last_part = FALSE; - guint32 last_position; - - /* Note for future enhancements */ - /* RFC 2046 specifies that when parsing the content of a - * multipart element, the program should not assume it will - * find the last boundary, and in particular, if the message - * is damaged during transport, the parsing should still be - * OK. - */ - - last_position = camel_seekable_stream_get_current_position ( - CAMEL_SEEKABLE_STREAM (stream)); - new_line = gmime_read_line_from_stream (stream); - - while (new_line && !end_of_part && !last_part) { - end_of_part = (strcmp (new_line, normal_boundary) == 0); - last_part = (strcmp (new_line, end_boundary) == 0); - if (!end_of_part && !last_part) { - g_free (new_line); - - last_position = - camel_seekable_stream_get_current_position ( - CAMEL_SEEKABLE_STREAM (stream)); - - new_line = gmime_read_line_from_stream (stream); - } - } - - if (new_line) - g_free (new_line); - else - last_part = TRUE; - - *end_position = last_position; - - return last_part; -} - - -static void -set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) -{ - CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper); - CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); - const gchar *boundary; - gchar *real_boundary_line; - gchar *end_boundary_line; - gboolean end_of_multipart; - CamelMimeBodyPart *body_part; - guint32 part_begining, part_end; - CamelSeekableSubstream *body_part_input_stream; - guint32 saved_stream_pos; - - /* Call parent class implementation. */ - parent_class->set_input_stream (data_wrapper, stream); - - boundary = camel_multipart_get_boundary (multipart); - g_return_if_fail (boundary); - - real_boundary_line = g_strdup_printf ("--%s", boundary); - end_boundary_line = g_strdup_printf ("--%s--", boundary); - - /* Read the prefix, if any. */ - end_of_multipart = separate_part (stream, real_boundary_line, - end_boundary_line, &part_end); - if (multipart->preface) - g_free (multipart->preface); - - /* Read all the real parts. */ - while (!end_of_multipart) { - /* Determine the position of the begining of the part. */ - part_begining = camel_seekable_stream_get_current_position (seekable_stream); - - body_part = camel_mime_body_part_new (); - - end_of_multipart = separate_part (stream, real_boundary_line, - end_boundary_line, - &part_end); - body_part_input_stream = CAMEL_SEEKABLE_SUBSTREAM ( - camel_seekable_substream_new_with_seekable_stream_and_bounds (seekable_stream, - part_begining, - part_end)); - - /* The seekable substream may change the position of - * the stream so we must save it before calling - * set_input_stream. - */ - saved_stream_pos = camel_seekable_stream_get_current_position (seekable_stream); - camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (body_part), - CAMEL_STREAM (body_part_input_stream)); - - /* restore the stream position */ - camel_seekable_stream_seek (seekable_stream, saved_stream_pos, CAMEL_STREAM_SET); - - /* add the body part to the multipart object */ - camel_multipart_add_part (multipart, body_part); - } - - /* g_string_assign (new_part, ""); */ - /* my_localize_part (new_part, stream, real_boundary_line, end_boundary_line); */ - - if (multipart->postface) g_free (multipart->postface); - /* if ( (new_part->str)[0] != '\0') multipart->postface = g_strdup (new_part->str); */ - - /* g_string_free (new_part, TRUE); */ - - g_free (real_boundary_line); - g_free (end_boundary_line); -} - -/* multi_part */ -static void -construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp) -{ - CamelDataWrapper *bodypart; - char *buf; - int len; - - d(printf("constructing multipart\n")); - - /* get/set boundary? */ - - while (camel_mime_parser_step(mp, &buf, &len) != HSCAN_MULTIPART_END) { - camel_mime_parser_unstep(mp); - bodypart = (CamelDataWrapper *)camel_mime_body_part_new(); - camel_data_wrapper_construct_from_parser(bodypart, mp); - camel_multipart_add_part((CamelMultipart *)dw, (CamelMimeBodyPart *)bodypart); - } -} diff --git a/camel/camel-simple-data-wrapper-stream.c b/camel/camel-simple-data-wrapper-stream.c index 5ee5363108..14e5383f5b 100644 --- a/camel/camel-simple-data-wrapper-stream.c +++ b/camel/camel-simple-data-wrapper-stream.c @@ -179,21 +179,6 @@ seek (CamelSeekableStream *stream, } -/* This handles destruction of the associated CamelDataWrapper. */ -/* Hm, this should never happen though, because we gtk_object_ref() the - wrapper. */ -static void -wrapper_destroy_cb (GtkObject *object, - gpointer data) -{ - CamelSimpleDataWrapperStream *stream; - - g_warning ("CamelSimpleDataWrapperStream: associated CamelSimpleDataWrapper was destroyed."); - stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (object); - stream->wrapper = NULL; -} - - /* GtkObject methods. */ static void @@ -276,10 +261,6 @@ camel_simple_data_wrapper_stream_construct (CamelSimpleDataWrapperStream *stream gtk_object_ref (GTK_OBJECT (wrapper)); stream->wrapper = wrapper; -#if 0 - gtk_signal_connect (GTK_OBJECT (wrapper), "destroy", - wrapper_destroy_cb, stream); -#endif } CamelStream * diff --git a/camel/camel-simple-data-wrapper.c b/camel/camel-simple-data-wrapper.c index d368a4ddfd..cb387ee04e 100644 --- a/camel/camel-simple-data-wrapper.c +++ b/camel/camel-simple-data-wrapper.c @@ -5,7 +5,6 @@ /* * * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> - * Michael Zucchi <notzed@helixcode.com> * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -45,15 +44,11 @@ static CamelDataWrapperClass *parent_class = NULL; /* Returns the class for a CamelDataWrapper */ #define CSDW_CLASS(so) CAMEL_SIMPLE_DATA_WRAPPER_CLASS (GTK_OBJECT (so)->klass) -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 CamelStream * get_output_stream (CamelDataWrapper *data_wrapper); -static void construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp); - - +static void construct_from_stream (CamelDataWrapper *dw, CamelStream *stream); static void camel_simple_data_wrapper_class_init (CamelSimpleDataWrapperClass *camel_simple_data_wrapper_class) @@ -68,10 +63,8 @@ camel_simple_data_wrapper_class_init (CamelSimpleDataWrapperClass *camel_simple_ /* virtual method overload */ camel_data_wrapper_class->write_to_stream = write_to_stream; - camel_data_wrapper_class->construct_from_stream = construct_from_stream; camel_data_wrapper_class->get_output_stream = get_output_stream; - - camel_data_wrapper_class->construct_from_parser = construct_from_parser; + camel_data_wrapper_class->construct_from_stream = construct_from_stream; gtk_object_class->finalize = finalize; } @@ -152,38 +145,6 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) parent_class->write_to_stream (data_wrapper, stream); } - -#define CMSDW_TMP_BUF_SIZE 100 -static void -construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) -{ - CamelSimpleDataWrapper *simple_data_wrapper = - CAMEL_SIMPLE_DATA_WRAPPER (data_wrapper); - gint nb_bytes_read; - static gchar *tmp_buf; - GByteArray *array; - - if (!tmp_buf) - tmp_buf = g_new (gchar, CMSDW_TMP_BUF_SIZE); - - array = simple_data_wrapper->byte_array; - if (array) - g_byte_array_free (array, FALSE); - - array = g_byte_array_new (); - simple_data_wrapper->byte_array = array; - nb_bytes_read = camel_stream_read (stream, tmp_buf, CMSDW_TMP_BUF_SIZE); - while (nb_bytes_read > 0) { - if (nb_bytes_read > 0) - g_byte_array_append (array, tmp_buf, nb_bytes_read); - nb_bytes_read = camel_stream_read (stream, tmp_buf, - CMSDW_TMP_BUF_SIZE); - }; -} - - - - /** * camel_simple_data_wrapper_set_text: set some text as data wrapper content * @simple_data_wrapper: SimpleDataWrapper object @@ -225,134 +186,9 @@ get_output_stream (CamelDataWrapper *data_wrapper) return parent_class->get_output_stream (data_wrapper); } -/* simple data wrapper */ static void -construct_from_parser(CamelDataWrapper *dw, CamelMimeParser *mp) +construct_from_stream(CamelDataWrapper *dw, CamelStream *stream) { - GByteArray *buffer; - char *buf; - int len; - off_t start, end; - CamelMimeFilter *fdec = NULL, *fch = NULL; - struct _header_content_type *ct; - int decid=-1, chrid=-1, cache=FALSE; - CamelStream *source; - char *encoding; - - d(printf("constructing simple-data-wrapper\n")); - - /* Ok, try and be smart. If we're storing a small message (typical) convert it, - and store it in memory as we parse it ... if not, throw away the conversion - and scan till the end ... */ - - /* if we can't seek, dont have a stream/etc, then we must cache it */ - source = camel_mime_parser_stream(mp); - gtk_object_ref((GtkObject *)source); - if (source == NULL - || !CAMEL_IS_SEEKABLE_STREAM(source)) - cache = TRUE; - - /* first, work out conversion, if any, required, we dont care about what we dont know about */ - encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL)); - if (encoding) { - if (!strcasecmp(encoding, "base64")) { - d(printf("Adding base64 decoder ...\n")); - fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC); - decid = camel_mime_parser_filter_add(mp, fdec); - } else if (!strcasecmp(encoding, "quoted-printable")) { - d(printf("Adding quoted-printable decoder ...\n")); - fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC); - decid = camel_mime_parser_filter_add(mp, fdec); - } - g_free(encoding); - } - - /* if we're doing text, then see if we have to convert it to UTF8 as well */ - ct = camel_mime_parser_content_type(mp); - if (header_content_type_is(ct, "text", "*")) { - const char *charset = header_content_type_param(ct, "charset"); - if (charset!=NULL - && !(strcasecmp(charset, "us-ascii")==0 - || strcasecmp(charset, "utf-8")==0)) { - d(printf("Adding conversion filter from %s to utf-8\n", charset)); - fch = (CamelMimeFilter *)camel_mime_filter_charset_new_convert(charset, "utf-8"); - if (fch) { - chrid = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)fch); - } else { - g_warning("Cannot convert '%s' to 'utf-8', message display may be corrupt", charset); - } - } - - } - - buffer = g_byte_array_new(); - - /* write to a memory buffer or something??? */ - start = camel_mime_parser_tell(mp); - while ( camel_mime_parser_step(mp, &buf, &len) != HSCAN_BODY_END ) { - if (buffer) { - if (buffer->len > 20480 && !cache) { - /* is this a 'big' message? Yes? We dont want to convert it all then.*/ - camel_mime_parser_filter_remove(mp, decid); - camel_mime_parser_filter_remove(mp, chrid); - decid = -1; - chrid = -1; - g_byte_array_free(buffer, TRUE); - buffer = NULL; - } else { - g_byte_array_append(buffer, buf, len); - } - } - } - - if (buffer) { - CamelStream *mem; - d(printf("Small message part, kept in memory!\n")); - mem = camel_stream_mem_new_with_byte_array(buffer, CAMEL_STREAM_MEM_READ); - camel_data_wrapper_set_output_stream (dw, mem); - } else { - CamelSeekableSubstream *sub; - CamelStreamFilter *filter; - - d(printf("Big message part, left on disk ...\n")); - - end = camel_mime_parser_tell(mp); - sub = (CamelSeekableSubstream *)camel_seekable_substream_new_with_seekable_stream_and_bounds ((CamelSeekableStream *)source, start, end); - if (fdec || fch) { - filter = camel_stream_filter_new_with_stream((CamelStream *)sub); - if (fdec) { - camel_mime_filter_reset(fdec); - camel_stream_filter_add(filter, fdec); - } - if (fch) { - camel_mime_filter_reset(fdec); - camel_stream_filter_add(filter, fch); - } - camel_data_wrapper_set_output_stream (dw, (CamelStream *)filter); - } else { - camel_data_wrapper_set_output_stream (dw, (CamelStream *)sub); - } - } - - camel_mime_parser_filter_remove(mp, decid); - camel_mime_parser_filter_remove(mp, chrid); - - if (fdec) - gtk_object_unref((GtkObject *)fdec); - if (fch) - gtk_object_unref((GtkObject *)fch); - gtk_object_unref((GtkObject *)source); - - /* FIXME: lookup in headers for content-type/encoding */ -#if 0 - /* trivial, mem-based ... */ - buffer = g_byte_array_new(); - start = camel_mime_parser_tell(mp); - while ( camel_mime_parser_step(mp, &buf, &len) != HSCAN_BODY_END ) { - g_byte_array_append(buffer, buf, len); - } - end = camel_mime_parser_tell(mp); - mem = camel_stream_mem_new_with_byte_array(buffer, CAMEL_STREAM_MEM_READ); - camel_data_wrapper_set_output_stream (dw, mem); -#endif + camel_data_wrapper_set_output_stream (dw, stream); } + diff --git a/camel/camel-simple-data-wrapper.h b/camel/camel-simple-data-wrapper.h index a16d1373a1..7ef69c5869 100644 --- a/camel/camel-simple-data-wrapper.h +++ b/camel/camel-simple-data-wrapper.h @@ -66,6 +66,10 @@ typedef struct { GtkType camel_simple_data_wrapper_get_type (void); +/* setup method. */ +void camel_simple_data_wrapper_stream_construct (CamelSimpleDataWrapperStream *stream, + CamelSimpleDataWrapper *wrapper); + /* public methods */ CamelSimpleDataWrapper *camel_simple_data_wrapper_new (void); diff --git a/camel/camel.c b/camel/camel.c index 56d2056db0..0121c1082f 100644 --- a/camel/camel.c +++ b/camel/camel.c @@ -25,6 +25,7 @@ #include <config.h> #include "camel.h" +#include <unicode.h> gint camel_init(void) @@ -41,5 +42,5 @@ camel_init(void) unicode_init (); - return data_wrapper_repository_init (); + return 0; } diff --git a/camel/data-wrapper-repository.c b/camel/data-wrapper-repository.c deleted file mode 100644 index f433383b85..0000000000 --- a/camel/data-wrapper-repository.c +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#include "data-wrapper-repository.h" -#include "camel-simple-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-multipart.h" -#include <string.h> -#include "hash-table-utils.h" - -static DataWrapperRepository _repository; -static int _initialized = -1; -GMimeContentField *_content_field; - - -/** - * data_wrapper_repository_init: initialize data wrapper repository - * - * initialize the data wrapper repository. When the repository has - * already been initialized, returns -1. - * - * Return value: 1 if correctly initialized returns -1. - **/ -gint -data_wrapper_repository_init () -{ - if (_initialized != -1) return -1; - _repository.mime_links = g_hash_table_new (g_strcase_hash, g_strcase_equal); - data_wrapper_repository_set_data_wrapper_type ("multipart", camel_multipart_get_type()); - - /* this is a temporary default so that Michael can use get_stream on text messages */ - data_wrapper_repository_set_data_wrapper_type ("text", camel_simple_data_wrapper_get_type()); - - /* this is for matt the great lopper */ - data_wrapper_repository_set_data_wrapper_type ("message/rfc822", camel_mime_message_get_type()); - _content_field = gmime_content_field_new (NULL, NULL); - _initialized = 1; - return 1; -} - -/** - * data_wrapper_repository_set_data_wrapper_type: associate a data wrapper object type to a mime type - * @mime_type: mime type - * @object_type: object type - * - * Associate an object type to a mime type. - **/ -void -data_wrapper_repository_set_data_wrapper_type (const gchar *mime_type, GtkType object_type) -{ - gboolean already_exists; - gchar *old_mime_type; - GtkType old_gtk_type; - - already_exists = g_hash_table_lookup_extended (_repository.mime_links, (gpointer)mime_type, - (gpointer)&old_mime_type, (gpointer)&old_gtk_type); - if (already_exists) - g_hash_table_insert (_repository.mime_links, (gpointer)old_mime_type, (gpointer)object_type); - else - g_hash_table_insert (_repository.mime_links, (gpointer)g_strdup (mime_type), (gpointer)object_type); -} - - - -/** - * data_wrapper_repository_get_data_wrapper_type: get the gtk type object associated to a mime type - * @mime_type: mime type - * - * returns the GtkType of the data wrapper object associated to - * a particular mime type. The mime type must be a character string - * of the form "type/subtype" or simply "type". When the complete - * mime type ("type/subtype") is not associated to any particular - * data wrapper object, this routine looks for a default data wrapper - * for the main mime type ("type"). When no particular association is - * found for this mime type, the type of the SimpleDataWrapper is - * returned. - * - * - * Return value: the associated data wrapper object type. - **/ -GtkType -data_wrapper_repository_get_data_wrapper_type (const gchar *mime_type) -{ - gboolean exists; - gchar *old_mime_type; - GtkType gtk_type; - - /* find if the complete mime type exists */ - exists = g_hash_table_lookup_extended (_repository.mime_links, (gpointer)mime_type, - (gpointer)&old_mime_type, (gpointer)>k_type); - if (exists) { /* the complete mime type exists, return it */ - return gtk_type; - } else { - /* the complete mime type association does not exists */ - /* is there an association for the main mime type ? */ - gmime_content_field_construct_from_string (_content_field, mime_type); - exists = g_hash_table_lookup_extended (_repository.mime_links, (gpointer)(_content_field->type), - (gpointer)&old_mime_type, (gpointer)>k_type); - - if (exists) /* the main mime type association exists */ - return gtk_type; - else - return camel_simple_data_wrapper_get_type(); - } - - - - -} - diff --git a/camel/data-wrapper-repository.h b/camel/data-wrapper-repository.h deleted file mode 100644 index a6c560859d..0000000000 --- a/camel/data-wrapper-repository.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef DATA_WRAPPER_REPOSITORY_H -#define DATA_WRAPPER_REPOSITORY_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <glib.h> -#include "camel-data-wrapper.h" - - - -typedef struct { - GHashTable *mime_links; -} DataWrapperRepository; - - -gint data_wrapper_repository_init (); -void data_wrapper_repository_set_data_wrapper_type (const gchar *mime_type, GtkType object_type); -GtkType data_wrapper_repository_get_data_wrapper_type (const gchar *mime_type); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* DATA_WRAPPER_REPOSITORY_H */ diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index c1920bdd1c..a22c273c2d 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -856,19 +856,9 @@ _get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) ((CamelMboxMessageContentInfo *)info->info.content)->pos, ((CamelMboxMessageContentInfo *)info->info.content)->endpos); message = camel_mime_message_new(); -#if 1 - { - CamelMimeParser *parser; - - parser = camel_mime_parser_new(); - camel_mime_parser_init_with_stream(parser, message_stream); - camel_data_wrapper_construct_from_parser(message, parser); - gtk_object_unref((GtkObject *)parser); - gtk_object_unref((GtkObject *)message_stream); - } -#else - camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (message), message_stream); -#endif + camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream); + gtk_object_unref((GtkObject *)message_stream); + /* init other fields? */ message->folder = folder; gtk_object_ref((GtkObject *)folder); diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index cf0d1763d3..7653dbdb6b 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -208,8 +208,8 @@ get_message_by_number (CamelFolder *folder, gint number, CamelException *ex) msgstream = camel_stream_mem_new_with_buffer (body, strlen (body), CAMEL_STREAM_MEM_READ); msg = camel_mime_message_new (); - camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (msg), - msgstream); + camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), + msgstream); return msg; } |