aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNotZed <NotZed@HelixCode.com>2000-04-24 14:05:41 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-04-24 14:05:41 +0800
commit8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07 (patch)
tree9667ffd1192096e68ebeaf1183c5d0a8d818d2e5
parent7455842584ee656cb375b52064ff8c23560c568b (diff)
downloadgsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.tar
gsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.tar.gz
gsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.tar.bz2
gsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.tar.lz
gsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.tar.xz
gsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.tar.zst
gsoc2013-evolution-8c9b0cc3f0d9cf8ca0c7b416a08d742b2694af07.zip
No longer call data_wrapper_repository_init.
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. 2a51,93 * 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. 4a96,102 (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. 11a110,111 (_get_message_by_uid): Use construct_from_stream() instead of creating our own parser. 16a117,131 (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 ... 19a135,136 (construct_from_stream): Removed! Job taken over by construct_from_parser. 24a142 (set_input_stream): REmoved. Replaced by construct_from_parser. svn path=/trunk/; revision=2577
-rw-r--r--camel/ChangeLog118
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-data-wrapper.c118
-rw-r--r--camel/camel-data-wrapper.h21
-rw-r--r--camel/camel-medium.c40
-rw-r--r--camel/camel-medium.h23
-rw-r--r--camel/camel-mime-message.c46
-rw-r--r--camel/camel-mime-part-utils.c279
-rw-r--r--camel/camel-mime-part-utils.h11
-rw-r--r--camel/camel-mime-part.c334
-rw-r--r--camel/camel-mime-part.h12
-rw-r--r--camel/camel-multipart.c161
-rw-r--r--camel/camel-simple-data-wrapper-stream.c19
-rw-r--r--camel/camel-simple-data-wrapper.c174
-rw-r--r--camel/camel-simple-data-wrapper.h4
-rw-r--r--camel/camel.c3
-rw-r--r--camel/data-wrapper-repository.c133
-rw-r--r--camel/data-wrapper-repository.h55
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c16
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c4
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)&gtk_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)&gtk_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;
}