aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog19
-rw-r--r--camel/camel-data-wrapper.c74
-rw-r--r--camel/camel-data-wrapper.h80
-rw-r--r--camel/camel-mime-filter-basic.h2
-rw-r--r--camel/camel-mime-message.c4
-rw-r--r--camel/camel-mime-part-utils.c360
-rw-r--r--camel/camel-mime-part.c127
-rw-r--r--camel/camel-mime-part.h19
-rw-r--r--camel/camel-mime-utils.h12
9 files changed, 198 insertions, 499 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index f766ba1b49..f07d498dab 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,22 @@
+2003-07-14 Jeffrey Stedfast <fejj@ximian.com>
+
+ * camel-mime-utils.h: Add the CamelMimePartEncodingType definition
+ here.
+
+ * camel-mime-part.h: Remove the CamelMimePartEncodingType
+ definition.
+
+ * camel-mime-part-utils.c
+ (simple_data_wrapper_construct_from_parser): Don't do any of the
+ auto-detection we used to do here anymore. Just read the content
+ into a memory buffer and record the encoding type.
+ (camel_mime_part_construct_content_from_parser): Don't mangle the
+ Content-Type struct here anymore.
+
+ * camel-data-wrapper.c (camel_data_wrapper_init): Init encoding to
+ DEFAULT.
+ (write_to_stream): If the stream needs to be decoded, decode it.
+
2003-07-15 Jeffrey Stedfast <fejj@ximian.com>
* camel-stream-fs.c (stream_read): If we read 0 bytes, then set
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c
index 7f9625d19b..ba898e0308 100644
--- a/camel/camel-data-wrapper.c
+++ b/camel/camel-data-wrapper.c
@@ -28,8 +28,9 @@
#include <errno.h>
#include "camel-data-wrapper.h"
-#include "camel-mime-utils.h"
#include "camel-stream.h"
+#include "camel-stream-filter.h"
+#include "camel-mime-filter-basic.h"
#include "camel-exception.h"
#include "camel-private.h"
@@ -72,8 +73,8 @@ camel_data_wrapper_init (gpointer object, gpointer klass)
pthread_mutex_init (&camel_data_wrapper->priv->stream_lock, NULL);
camel_data_wrapper->mime_type = header_content_type_new ("application", "octet-stream");
+ camel_data_wrapper->encoding = CAMEL_MIME_PART_ENCODING_DEFAULT;
camel_data_wrapper->offline = FALSE;
- camel_data_wrapper->rawtext = TRUE;
}
static void
@@ -89,30 +90,33 @@ camel_data_wrapper_finalize (CamelObject *object)
header_content_type_unref (camel_data_wrapper->mime_type);
if (camel_data_wrapper->stream)
- camel_object_unref (CAMEL_OBJECT (camel_data_wrapper->stream));
+ camel_object_unref (camel_data_wrapper->stream);
}
CamelType
camel_data_wrapper_get_type (void)
{
- static CamelType camel_data_wrapper_type = CAMEL_INVALID_TYPE;
-
- if (camel_data_wrapper_type == CAMEL_INVALID_TYPE) {
- camel_data_wrapper_type = camel_type_register (CAMEL_OBJECT_TYPE, "CamelDataWrapper",
- sizeof (CamelDataWrapper),
- sizeof (CamelDataWrapperClass),
- (CamelObjectClassInitFunc) camel_data_wrapper_class_init,
- NULL,
- (CamelObjectInitFunc) camel_data_wrapper_init,
- (CamelObjectFinalizeFunc) camel_data_wrapper_finalize);
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (type == CAMEL_INVALID_TYPE) {
+ type = camel_type_register (CAMEL_OBJECT_TYPE,
+ "CamelDataWrapper",
+ sizeof (CamelDataWrapper),
+ sizeof (CamelDataWrapperClass),
+ (CamelObjectClassInitFunc) camel_data_wrapper_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_data_wrapper_init,
+ (CamelObjectFinalizeFunc) camel_data_wrapper_finalize);
}
-
- return camel_data_wrapper_type;
+
+ return type;
}
static int
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
{
+ CamelMimeFilter *filter;
+ CamelStream *fstream;
int ret;
if (data_wrapper->stream == NULL) {
@@ -125,7 +129,31 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
return -1;
}
- ret = camel_stream_write_to_stream (data_wrapper->stream, stream);
+ fstream = (CamelStream *) camel_stream_filter_new_with_stream (data_wrapper->stream);
+
+ switch (data_wrapper->encoding) {
+ case CAMEL_MIME_PART_ENCODING_BASE64:
+ filter = (CamelMimeFilter *) camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ camel_object_unref (filter);
+ break;
+ case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
+ filter = (CamelMimeFilter *) camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_QP_DEC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ camel_object_unref (filter);
+ break;
+ case CAMEL_MIME_PART_ENCODING_UUENCODE:
+ filter = (CamelMimeFilter *) camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_UU_DEC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
+ camel_object_unref (filter);
+ break;
+ default:
+ break;
+ }
+
+ ret = camel_stream_write_to_stream (fstream, stream);
+ camel_object_unref (fstream);
+
CAMEL_DATA_WRAPPER_UNLOCK (data_wrapper, stream_lock);
return ret;
@@ -164,10 +192,10 @@ static int
construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
{
if (data_wrapper->stream)
- camel_object_unref((CamelObject *)data_wrapper->stream);
-
+ camel_object_unref (data_wrapper->stream);
+
data_wrapper->stream = stream;
- camel_object_ref (CAMEL_OBJECT (stream));
+ camel_object_ref (stream);
return 0;
}
@@ -193,7 +221,7 @@ camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
static void
-set_mime_type (CamelDataWrapper *data_wrapper, const gchar *mime_type)
+set_mime_type (CamelDataWrapper *data_wrapper, const char *mime_type)
{
if (data_wrapper->mime_type)
header_content_type_unref (data_wrapper->mime_type);
@@ -214,7 +242,7 @@ set_mime_type (CamelDataWrapper *data_wrapper, const gchar *mime_type)
**/
void
camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
- const gchar *mime_type)
+ const char *mime_type)
{
g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
g_return_if_fail (mime_type != NULL);
@@ -222,7 +250,7 @@ camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
CDW_CLASS (data_wrapper)->set_mime_type (data_wrapper, mime_type);
}
-static gchar *
+static char *
get_mime_type (CamelDataWrapper *data_wrapper)
{
return header_content_type_simple (data_wrapper->mime_type);
@@ -235,7 +263,7 @@ get_mime_type (CamelDataWrapper *data_wrapper)
* Return value: the text form of the data wrapper's MIME type,
* which the caller must free.
**/
-gchar *
+char *
camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper)
{
g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), NULL);
diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h
index d8c7fbe50b..03fbd013d3 100644
--- a/camel/camel-data-wrapper.h
+++ b/camel/camel-data-wrapper.h
@@ -1,26 +1,25 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* camel-data-wrapper.h : Abstract class for a data wrapper */
-
/*
+ * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Michael Zucchi <notzed@ximian.com>
+ * Jeffrey Stedfast <fejj@ximian.com>
*
- * Author :
- * Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Copyright 1999-2003 Ximian, Inc. (www.ximian.com)
*
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.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 free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
+ * 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.
*
- * 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 Street #330, Boston, MA 02111-1307, USA.
*
- * 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
*/
@@ -30,66 +29,67 @@
#ifdef __cplusplus
extern "C" {
#pragma }
-#endif /* __cplusplus }*/
+#endif /* __cplusplus */
#include <glib.h>
#include <camel/camel-object.h>
+#include <camel/camel-mime-utils.h>
#define CAMEL_DATA_WRAPPER_TYPE (camel_data_wrapper_get_type ())
#define CAMEL_DATA_WRAPPER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_DATA_WRAPPER_TYPE, CamelDataWrapper))
#define CAMEL_DATA_WRAPPER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_DATA_WRAPPER_TYPE, CamelDataWrapperClass))
#define CAMEL_IS_DATA_WRAPPER(o) (CAMEL_CHECK_TYPE((o), CAMEL_DATA_WRAPPER_TYPE))
-struct _CamelDataWrapper
-{
+struct _CamelDataWrapper {
CamelObject parent_object;
struct _CamelDataWrapperPrivate *priv;
+ CamelMimePartEncodingType encoding;
+
CamelContentType *mime_type;
CamelStream *stream;
unsigned int offline:1;
- unsigned int rawtext:1;
};
typedef struct {
CamelObjectClass parent_class;
-
+
/* Virtual methods */
void (*set_mime_type) (CamelDataWrapper *data_wrapper,
- const gchar * mime_type);
- gchar * (*get_mime_type) (CamelDataWrapper *data_wrapper);
+ const char *mime_type);
+ char * (*get_mime_type) (CamelDataWrapper *data_wrapper);
CamelContentType * (*get_mime_type_field) (CamelDataWrapper *data_wrapper);
void (*set_mime_type_field) (CamelDataWrapper *data_wrapper,
CamelContentType *mime_type_field);
-
+
int (*write_to_stream) (CamelDataWrapper *data_wrapper,
CamelStream *stream);
-
+
int (*construct_from_stream) (CamelDataWrapper *data_wrapper,
CamelStream *);
-
+
gboolean (*is_offline) (CamelDataWrapper *data_wrapper);
-
} CamelDataWrapperClass;
/* Standard Camel function */
CamelType camel_data_wrapper_get_type (void);
/* public methods */
-CamelDataWrapper * camel_data_wrapper_new(void);
-int camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
- CamelStream *stream);
-void camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
- const gchar *mime_type);
-gchar * camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper);
-CamelContentType * camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper);
-void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
- CamelContentType *mime_type);
-
-int camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
-
-gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper);
+CamelDataWrapper *camel_data_wrapper_new(void);
+int camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream);
+void camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
+ const char *mime_type);
+char *camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper);
+CamelContentType *camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper);
+void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type);
+
+int camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *stream);
+
+gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper);
#ifdef __cplusplus
}
diff --git a/camel/camel-mime-filter-basic.h b/camel/camel-mime-filter-basic.h
index d07edee107..f380f5e7a4 100644
--- a/camel/camel-mime-filter-basic.h
+++ b/camel/camel-mime-filter-basic.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Copyright (C) 2000 Ximian Inc.
+ * Copyright (C) 2000-2003 Ximian Inc.
*
* Authors: Michael Zucchi <notzed@ximian.com>
*
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index 9398fa4eb2..3bbce53e68 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -6,7 +6,7 @@
* Michael Zucchi <notzed@ximian.com>
* Jeffrey Stedfast <fejj@ximian.com>
*
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
+ * Copyright 1999-2003 Ximian, Inc. (www.ximian.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -750,7 +750,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes
d(printf("have charset, trying conversion/etc\n"));
- /* now the 'bestenc' can has told us what the best encoding is, we can use that to create
+ /* now that 'bestenc' has told us what the best encoding is, we can use that to create
a charset conversion filter as well, and then re-add the bestenc to filter the
result to find the best encoding to use as well */
diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c
index 4b815475e5..af4d7c1161 100644
--- a/camel/camel-mime-part-utils.c
+++ b/camel/camel-mime-part-utils.c
@@ -5,7 +5,7 @@
* Michael Zucchi <notzed@ximian.com>
* Jeffrey Stedfast <fejj@ximian.com>
*
- * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
+ * Copyright 1999-2003 Ximian, Inc. (www.ximian.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -53,278 +53,21 @@
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))
#include <stdio.h>*/
-/* example: <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> */
-
-static const char *
-check_html_charset(char *buffer, int length)
-{
- CamelHTMLParser *hp;
- const char *charset = NULL;
- camel_html_parser_t state;
- struct _header_content_type *ct;
-
- /* if we need to first base64/qp decode, do this here, sigh */
- hp = camel_html_parser_new();
- camel_html_parser_set_data(hp, buffer, length, TRUE);
-
- do {
- const char *data;
- int len;
- const char *val;
-
- state = camel_html_parser_step(hp, &data, &len);
-
- /* example: <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> */
-
- switch(state) {
- case CAMEL_HTML_PARSER_ELEMENT:
- val = camel_html_parser_tag(hp);
- d(printf("Got tag: %s\n", val));
- if (strcasecmp(val, "meta") == 0
- && (val = camel_html_parser_attr(hp, "http-equiv"))
- && strcasecmp(val, "content-type") == 0
- && (val = camel_html_parser_attr(hp, "content"))
- && (ct = header_content_type_decode(val))) {
- charset = header_content_type_param(ct, "charset");
- charset = e_iconv_charset_name (charset);
- header_content_type_unref(ct);
- }
- break;
- default:
- /* ignore everything else */
- break;
- }
- } while (charset == NULL && state != CAMEL_HTML_PARSER_EOF);
-
- camel_object_unref (hp);
-
- return charset;
-}
-
-static GByteArray *
-convert_buffer (GByteArray *in, const char *to, const char *from)
-{
- size_t inleft, outleft, outlen, converted = 0;
- GByteArray *out = NULL;
- const char *inbuf;
- char *outbuf;
- iconv_t cd;
-
- if (in->len == 0)
- return g_byte_array_new();
-
- d(printf("converting buffer from %s to %s:\n", from, to));
- d(fwrite(in->data, 1, (int)in->len, stdout));
- d(printf("\n"));
-
- cd = e_iconv_open(to, from);
- if (cd == (iconv_t) -1) {
- g_warning ("Cannot convert from '%s' to '%s': %s", from, to, strerror (errno));
- return NULL;
- }
-
- outlen = in->len * 2 + 16;
- out = g_byte_array_new ();
- g_byte_array_set_size (out, outlen);
-
- inbuf = in->data;
- inleft = in->len;
-
- do {
- outbuf = out->data + converted;
- outleft = outlen - converted;
-
- converted = e_iconv (cd, &inbuf, &inleft, &outbuf, &outleft);
- if (converted == (size_t) -1) {
- if (errno != E2BIG && errno != EINVAL)
- goto fail;
- }
-
- /*
- * E2BIG There is not sufficient room at *outbuf.
- *
- * We just need to grow our outbuffer and try again.
- */
-
- converted = outbuf - (char *)out->data;
- if (errno == E2BIG) {
- outlen += inleft * 2 + 16;
- out = g_byte_array_set_size (out, outlen);
- outbuf = out->data + converted;
- }
-
- } while (errno == E2BIG && inleft > 0);
-
- /*
- * EINVAL An incomplete multibyte sequence has been encoun­
- * tered in the input.
- *
- * We'll just have to ignore it...
- */
-
- /* flush the iconv conversion */
- e_iconv (cd, NULL, NULL, &outbuf, &outleft);
-
- /* now set the true length on the GByteArray */
- converted = outbuf - (char *)out->data;
- g_byte_array_set_size (out, converted);
-
- d(printf("converted data:\n"));
- d(fwrite(out->data, 1, (int)out->len, stdout));
- d(printf("\n"));
-
- e_iconv_close (cd);
-
- return out;
-
- fail:
- g_warning ("Cannot convert from '%s' to '%s': %s", from, to, strerror (errno));
-
- g_byte_array_free (out, TRUE);
-
- e_iconv_close (cd);
-
- return NULL;
-}
-
-/* We don't really use the charset argument except for debugging... */
-static gboolean
-broken_windows_charset (GByteArray *buffer, const char *charset)
-{
- register unsigned char *inptr;
- unsigned char *inend;
-
- inptr = buffer->data;
- inend = inptr + buffer->len;
-
- while (inptr < inend) {
- register unsigned char c = *inptr++;
-
- if (c >= 128 && c <= 159) {
- g_warning ("Encountered Windows charset parading as %s", charset);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static gboolean
-is_7bit (GByteArray *buffer)
-{
- register unsigned int i;
-
- for (i = 0; i < buffer->len; i++)
- if (buffer->data[i] > 127)
- return FALSE;
-
- return TRUE;
-}
-
-static const char *iso_charsets[] = {
- "us-ascii",
- "iso-8859-1",
- "iso-8859-2",
- "iso-8859-3",
- "iso-8859-4",
- "iso-8859-5",
- "iso-8859-6",
- "iso-8859-7",
- "iso-8859-8",
- "iso-8859-9",
- "iso-8859-10",
- "iso-8859-11",
- "iso-8859-12",
- "iso-8859-13",
- "iso-8859-14",
- "iso-8859-15",
- "iso-8859-16"
-};
-
-#define NUM_ISO_CHARSETS (sizeof (iso_charsets) / sizeof (iso_charsets[0]))
-
-static const char *
-canon_charset_name (const char *charset)
-{
- const char *ptr;
- char *endptr;
- int iso;
-
- if (strncasecmp (charset, "iso", 3) != 0)
- return charset;
-
- ptr = charset + 3;
- if (*ptr == '-' || *ptr == '_')
- ptr++;
-
- /* if it's not an iso-8859-# charset, we don't care about it */
- if (strncmp (ptr, "8859", 4) != 0)
- return charset;
-
- ptr += 4;
- if (*ptr == '-' || *ptr == '_')
- ptr++;
-
- iso = strtoul (ptr, &endptr, 10);
- if (endptr == ptr || *endptr != '\0')
- return charset;
-
- if (iso >= NUM_ISO_CHARSETS)
- return charset;
-
- return iso_charsets[iso];
-}
-
/* simple data wrapper */
static void
simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, CamelMimeParser *mp)
{
- CamelMimeFilter *fdec = NULL, *fcrlf = NULL;
- CamelMimeFilterBasicType enctype = 0;
- size_t len;
- int decid = -1, crlfid = -1;
struct _header_content_type *ct;
const char *charset = NULL;
char *encoding, *buf;
GByteArray *buffer;
CamelStream *mem;
+ size_t len;
d(printf ("simple_data_wrapper_construct_from_parser()\n"));
/* 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"));
- enctype = CAMEL_MIME_FILTER_BASIC_BASE64_DEC;
- } else if (!strcasecmp (encoding, "quoted-printable")) {
- d(printf("Adding quoted-printable decoder ...\n"));
- enctype = CAMEL_MIME_FILTER_BASIC_QP_DEC;
- } else if (!strcasecmp (encoding, "x-uuencode")) {
- d(printf("Adding uudecoder ...\n"));
- enctype = CAMEL_MIME_FILTER_BASIC_UU_DEC;
- }
- g_free (encoding);
-
- if (enctype != 0) {
- fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(enctype);
- decid = camel_mime_parser_filter_add (mp, fdec);
- }
- }
-
- /* If we're doing text, we also need to do CRLF->LF and may have to convert it to UTF8 as well. */
- ct = camel_mime_parser_content_type (mp);
- if (header_content_type_is (ct, "text", "*")) {
- charset = header_content_type_param (ct, "charset");
- charset = e_iconv_charset_name (charset);
-
- if (fdec) {
- d(printf ("Adding CRLF conversion filter\n"));
- fcrlf = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
- crlfid = camel_mime_parser_filter_add (mp, fcrlf);
- }
- }
/* read in the entire content */
buffer = g_byte_array_new ();
@@ -333,86 +76,22 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, CamelMimeParser
g_byte_array_append (buffer, buf, len);
}
- /* check for broken Outlook/Web mailers that like to send html marked as text/plain */
- if (header_content_type_is (ct, "text", "plain")) {
- register const unsigned char *inptr;
- const unsigned char *inend;
-
- inptr = buffer->data;
- inend = inptr + buffer->len;
-
- while (inptr < inend && isspace ((int) *inptr))
- inptr++;
-
- if (((inend-inptr) > 5 && g_ascii_strncasecmp(inptr, "<html", 5) == 0)
- || ((inend-inptr) > 9 && g_ascii_strncasecmp(inptr, "<!doctype", 9) == 0)) {
- /* re-tag as text/html */
- g_free (ct->subtype);
- ct->subtype = g_strdup ("html");
- }
- }
+ d(printf("message part kept in memory!\n"));
- /* Possible Lame Mailer Alert... check the META tags for a charset */
- if (!charset && header_content_type_is (ct, "text", "html")) {
- if ((charset = check_html_charset (buffer->data, buffer->len)))
- header_content_type_set_param (ct, "charset", charset);
- }
+ mem = camel_stream_mem_new_with_byte_array (buffer);
+ camel_data_wrapper_construct_from_stream (dw, mem);
+ camel_object_unref (mem);
- /* if we need to do charset conversion, see if we can/it works/etc */
- if (charset && !(strcasecmp (charset, "us-ascii") == 0
- || strcasecmp (charset, "utf-8") == 0
- || strncasecmp (charset, "x-", 2) == 0)) {
- GByteArray *out;
-
- /* You often see Microsoft Windows users announcing their texts
- * as being in ISO-8859-1 even when in fact they contain funny
- * characters from the Windows-CP1252 superset.
- */
- charset = canon_charset_name (charset);
- if (!strncasecmp (charset, "iso-8859", 8)) {
- /* check for Windows-specific chars... */
- if (broken_windows_charset (buffer, charset))
- charset = camel_charset_iso_to_windows (charset);
- }
-
- out = convert_buffer (buffer, "UTF-8", charset);
- if (out) {
- /* converted ok, use this data instead */
- g_byte_array_free(buffer, TRUE);
- dw->rawtext = FALSE;
- buffer = out;
- } else {
- /* else failed to convert, leave as raw? */
- g_warning("Storing text as raw, unknown charset '%s' or invalid format", charset);
- dw->rawtext = TRUE;
- }
- } else if (header_content_type_is (ct, "text", "*")) {
- if (charset == NULL || !strcasecmp (charset, "us-ascii")) {
- /* check that it's 7bit */
- dw->rawtext = !is_7bit (buffer);
- } else if (!strncasecmp (charset, "x-", 2)) {
- /* we're not even going to bother trying to convert, so set the
- rawtext bit to TRUE and let the mailer deal with it. */
- dw->rawtext = TRUE;
- } else if (!strcasecmp (charset, "utf-8") && buffer->len) {
- /* check that it is valid utf8 */
- dw->rawtext = !g_utf8_validate (buffer->data, buffer->len, NULL);
+ if (encoding) {
+ if (!strcasecmp (encoding, "base64")) {
+ dw->encoding = CAMEL_MIME_PART_ENCODING_BASE64;
+ } else if (!strcasecmp (encoding, "quoted-printable")) {
+ dw->encoding = CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE;
+ } else if (!strcasecmp (encoding, "x-uuencode")) {
+ dw->encoding = CAMEL_MIME_PART_ENCODING_UUENCODE;
}
+ g_free (encoding);
}
-
- d(printf("message part kept in memory!\n"));
-
- mem = camel_stream_mem_new_with_byte_array(buffer);
- camel_data_wrapper_construct_from_stream(dw, mem);
- camel_object_unref((CamelObject *)mem);
-
- camel_mime_parser_filter_remove(mp, decid);
- camel_mime_parser_filter_remove(mp, crlfid);
-
- if (fdec)
- camel_object_unref((CamelObject *)fdec);
- if (fcrlf)
- camel_object_unref((CamelObject *)fcrlf);
}
/* This replaces the data wrapper repository ... and/or could be replaced by it? */
@@ -423,7 +102,7 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParse
CamelContentType *ct;
ct = camel_mime_parser_content_type (mp);
-
+
switch (camel_mime_parser_state (mp)) {
case HSCAN_HEADER:
d(printf("Creating body part\n"));
@@ -460,15 +139,6 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParse
/* 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 (dw));
camel_medium_set_content_object ((CamelMedium *)dw, content);
-
- /* Note: we don't set ct as the content-object's mime-type above because
- * camel_medium_set_content_object() may re-write the Content-Type header
- * (see CamelMimePart::set_content_object) if we did that (which is a Bad Thing).
- * However, if we set it *afterward*, we can still use any special auto-detections
- * that we found in simple_data_wrapper_construct_from_parser(). This is important
- * later when we go to render the MIME parts in mail-format.c */
- camel_data_wrapper_set_mime_type_field (content, ct);
-
camel_object_unref (content);
}
}
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 343248715b..e6ab427f49 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -75,7 +75,7 @@ static CamelMediumClass *parent_class=NULL;
static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
static int construct_from_stream (CamelDataWrapper *dw, CamelStream *s);
-/* from CamelMedia */
+/* from CamelMedium */
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);
@@ -626,7 +626,6 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream)
{
CamelMimePart *mp = CAMEL_MIME_PART(data_wrapper);
CamelMedium *medium = CAMEL_MEDIUM(data_wrapper);
- CamelStream *ostream = stream;
CamelDataWrapper *content;
int total = 0;
int count;
@@ -667,89 +666,75 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream)
return -1;
total += count;
- content = camel_medium_get_content_object(medium);
+ content = camel_medium_get_content_object (medium);
if (content) {
- /* I dont really like this here, but i dont know where else it might go ... */
-#define CAN_THIS_GO_ELSEWHERE
-#ifdef CAN_THIS_GO_ELSEWHERE
- CamelMimeFilter *filter = NULL;
- CamelStreamFilter *filter_stream = NULL;
- CamelMimeFilter *charenc = NULL;
- const char *filename;
- const char *charset;
-
- switch (mp->encoding) {
- case CAMEL_MIME_PART_ENCODING_BASE64:
- filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_ENC);
- break;
- case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
- filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_ENC);
- break;
- case CAMEL_MIME_PART_ENCODING_UUENCODE:
- filename = camel_mime_part_get_filename (mp);
- count = camel_stream_printf (ostream, "begin 644 %s\n", filename ? filename : "untitled");
+ if (mp->encoding != content->encoding) {
+ /* we need to (re)encode the content stream */
+ CamelStream *filter_stream = NULL;
+ CamelMimeFilter *filter = NULL;
+ const char *filename;
+
+ filter_stream = (CamelStream *) camel_stream_filter_new_with_stream (stream);
+ switch (mp->encoding) {
+ case CAMEL_MIME_PART_ENCODING_BASE64:
+ filter = (CamelMimeFilter *) camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_BASE64_ENC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (filter_stream), filter);
+ camel_object_unref (filter);
+ break;
+ case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
+ filter = (CamelMimeFilter *) camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_QP_ENC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (filter_stream), filter);
+ camel_object_unref (filter);
+ break;
+ case CAMEL_MIME_PART_ENCODING_UUENCODE:
+ filename = camel_mime_part_get_filename (mp);
+ count = camel_stream_printf (stream, "begin 0644 %s\n", filename ? filename : "unknown");
+ if (count == -1) {
+ camel_object_unref (filter_stream);
+ return -1;
+ }
+
+ total += count;
+
+ filter = (CamelMimeFilter *) camel_mime_filter_basic_new_type (CAMEL_MIME_FILTER_BASIC_UU_ENC);
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (filter_stream), filter);
+ camel_object_unref (filter);
+ break;
+ default:
+ break;
+ }
+
+ count = camel_data_wrapper_write_to_stream (content, filter_stream);
+ camel_stream_flush (filter_stream);
+ camel_object_unref (filter_stream);
+
if (count == -1)
return -1;
- total += count;
- filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_UU_ENC);
- break;
- default:
- break;
- }
-
- if (!content->rawtext && header_content_type_is(mp->content_type, "text", "*")) {
- charset = header_content_type_param(mp->content_type, "charset");
- if (charset && !(!strcasecmp(charset, "us-ascii") || !strcasecmp(charset, "utf-8"))) {
- charenc = (CamelMimeFilter *)camel_mime_filter_charset_new_convert("UTF-8", charset);
- }
- }
-
- if (filter || charenc) {
- filter_stream = camel_stream_filter_new_with_stream(stream);
- /* if we have a character encoder, add that always */
- if (charenc) {
- camel_stream_filter_add(filter_stream, charenc);
- camel_object_unref((CamelObject *)charenc);
- }
+ total += count;
- /* we only re-do crlf on encoded blocks */
- if (filter && header_content_type_is(mp->content_type, "text", "*")) {
- CamelMimeFilter *crlf = camel_mime_filter_crlf_new(CAMEL_MIME_FILTER_CRLF_ENCODE,
- CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
+ if (mp->encoding == CAMEL_MIME_PART_ENCODING_UUENCODE) {
+ /* FIXME: get rid of this special-case x-uuencode crap */
+ count = camel_stream_write (stream, "end\n", 4);
+ if (count == -1)
+ return -1;
- camel_stream_filter_add(filter_stream, crlf);
- camel_object_unref((CamelObject *)crlf);
+ total += count;
}
+ } else {
+ /* write the content out raw... */
+ if (camel_stream_reset (content->stream) == -1)
+ return -1;
- if (filter) {
- camel_stream_filter_add(filter_stream, filter);
- camel_object_unref((CamelObject *)filter);
- }
+ count = camel_stream_write_to_stream (content->stream, stream);
- stream = (CamelStream *)filter_stream;
- }
-
-#endif
-
- count = camel_data_wrapper_write_to_stream(content, stream);
-
- if (filter_stream) {
- camel_stream_flush((CamelStream *)filter_stream);
- camel_object_unref((CamelObject *)filter_stream);
- }
- if (count == -1)
- return -1;
- total += count;
-
- if (mp->encoding == CAMEL_MIME_PART_ENCODING_UUENCODE) {
- count = camel_stream_write (ostream, "end\n", 4);
if (count == -1)
return -1;
+
total += count;
}
} else {
- g_warning("No content for medium, nothing to write");
+ g_warning ("No content for medium, nothing to write");
}
return total;
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index c925643f24..d53b660f50 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -31,7 +31,7 @@
#ifdef __cplusplus
extern "C" {
#pragma }
-#endif /* __cplusplus }*/
+#endif /* __cplusplus */
#include <camel/camel-medium.h>
#include <camel/camel-mime-utils.h>
@@ -42,23 +42,8 @@ extern "C" {
#define CAMEL_MIME_PART_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_MIME_PART_TYPE, CamelMimePartClass))
#define CAMEL_IS_MIME_PART(o) (CAMEL_CHECK_TYPE((o), CAMEL_MIME_PART_TYPE))
-/* note, if you change this, make sure you change the 'encodings' array in camel-mime-part.c */
-enum _CamelMimePartEncodingType {
- CAMEL_MIME_PART_ENCODING_DEFAULT,
- CAMEL_MIME_PART_ENCODING_7BIT,
- CAMEL_MIME_PART_ENCODING_8BIT,
- CAMEL_MIME_PART_ENCODING_BASE64,
- CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE,
- CAMEL_MIME_PART_ENCODING_BINARY,
- CAMEL_MIME_PART_ENCODING_UUENCODE,
- CAMEL_MIME_PART_NUM_ENCODINGS
-};
-typedef enum _CamelMimePartEncodingType CamelMimePartEncodingType;
-
-
/* Do not change these values directly, you would regret it one day */
-struct _CamelMimePart
-{
+struct _CamelMimePart {
CamelMedium parent_object;
CamelContentType *content_type;
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index b949ffcf98..b58bcbea72 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -42,6 +42,18 @@ extern "C" {
#define CAMEL_UUDECODE_STATE_END (1 << 17)
#define CAMEL_UUDECODE_STATE_MASK (CAMEL_UUDECODE_STATE_BEGIN | CAMEL_UUDECODE_STATE_END)
+/* note, if you change this, make sure you change the 'encodings' array in camel-mime-part.c */
+typedef enum _CamelMimePartEncodingType {
+ CAMEL_MIME_PART_ENCODING_DEFAULT,
+ CAMEL_MIME_PART_ENCODING_7BIT,
+ CAMEL_MIME_PART_ENCODING_8BIT,
+ CAMEL_MIME_PART_ENCODING_BASE64,
+ CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE,
+ CAMEL_MIME_PART_ENCODING_BINARY,
+ CAMEL_MIME_PART_ENCODING_UUENCODE,
+ CAMEL_MIME_PART_NUM_ENCODINGS
+} CamelMimePartEncodingType;
+
/* a list of references for this message */
struct _header_references {
struct _header_references *next;