diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 17 | ||||
-rw-r--r-- | camel/Makefile.am | 2 | ||||
-rw-r--r-- | camel/camel-formatter.c | 8 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 54 | ||||
-rw-r--r-- | camel/camel-seekable-substream.c | 24 | ||||
-rw-r--r-- | camel/camel-stream-b64.c | 305 | ||||
-rw-r--r-- | camel/camel-stream-b64.h | 116 | ||||
-rw-r--r-- | camel/camel-stream.c | 2 | ||||
-rw-r--r-- | camel/gmime-base64.c | 9 | ||||
-rw-r--r-- | camel/gmime-base64.h | 2 |
10 files changed, 529 insertions, 10 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 26d6417718..fe9cac7d0e 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,8 +1,25 @@ +2000-02-21 bertrand <Bertrand.Guiheneuf@aful.org> + + * camel-formatter.c (lookup_unique_id): + awful hack to test get_output_stream. + * camel-stream-b64.[ch] : + b64 encoding/decoding is now implemented as + a stream. + + +2000-02-21 bertrand <Bertrand.Guiheneuf@aful.org> + + * camel-seekable-substream.c (_reemit_parent_signal): + emit "data_available" when parent stream emits it. + + + 2000-02-21 NotZed <NotZed@HelixCode.com> * providers/mbox/Makefile.am: Uh, fixed LIBADD again. What was there was never ever going to work, wasn't it tested? + 2000-02-21 Dan Winship <danw@helixcode.com> * camel-session.h: (struct _CamelSession): Add authenticator. diff --git a/camel/Makefile.am b/camel/Makefile.am index cff67fc736..2d647875c9 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -58,6 +58,7 @@ libcamel_la_SOURCES = \ camel-session.c \ camel-store.c \ camel-stream.c \ + camel-stream-b64.c \ camel-stream-buffered-fs.c \ camel-stream-fs.c \ camel-stream-mem.c \ @@ -100,6 +101,7 @@ libcamelinclude_HEADERS = \ camel-session.h \ camel-store.h \ camel-stream.h \ + camel-stream-b64.h \ camel-stream-buffered-fs.h \ camel-stream-fs.h \ camel-stream-mem.h \ diff --git a/camel/camel-formatter.c b/camel/camel-formatter.c index 6f66d8293a..469a096689 100644 --- a/camel/camel-formatter.c +++ b/camel/camel-formatter.c @@ -235,9 +235,15 @@ typedef void (*mime_handler_fn) (CamelFormatter *formatter, static gchar* lookup_unique_id (CamelDataWrapper* root, CamelDataWrapper* child) { + /* ** FIXME : replace this with a string representing + the location of the objetc in the tree */ /* TODO: assert our return value != NULL */ - return "NYI"; + gchar *temp_hack_uid; + + temp_hack_uid = g_strdup_printf ("%p", camel_data_wrapper_get_output_stream (child)); + + return temp_hack_uid; } static GHashTable* mime_function_table; diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 082f62fab0..bfd511ca13 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -42,6 +42,7 @@ #include "camel-mime-part-utils.h" #include "gmime-base64.h" #include "camel-seekable-substream.h" +#include "camel-stream-b64.h" typedef enum { @@ -606,13 +607,31 @@ _get_content_object (CamelMedium *medium) { CamelMimePart *mime_part = CAMEL_MIME_PART (medium); CamelStream *stream; + CamelStream *decoded_stream; CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_content_object entering\n"); if (!medium->content ) { stream = mime_part->content_input_stream; + decoded_stream = stream; + + switch (mime_part->encoding) { - camel_mime_part_construct_content_from_stream (mime_part, stream); + case CAMEL_MIME_PART_ENCODING_DEFAULT: + case CAMEL_MIME_PART_ENCODING_7BIT: + case CAMEL_MIME_PART_ENCODING_8BIT: + case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE: + break; + + case CAMEL_MIME_PART_ENCODING_BASE64: + decoded_stream = camel_stream_b64_new_with_input_stream (stream); + camel_stream_b64_set_mode (CAMEL_STREAM_B64 (decoded_stream), + CAMEL_STREAM_B64_DECODER); + break; + } + + + camel_mime_part_construct_content_from_stream (mime_part, decoded_stream); } else { CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_content_object part has a pointer " @@ -663,7 +682,7 @@ _write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream) g_warning ("Class `%s' does not implement `get_stream'", gtk_type_name (GTK_OBJECT (content)->klass->type)); } - gmime_encode_base64 (wrapper_stream, stream); + gmime_encode_base64_to_stream (wrapper_stream, stream); break; default: g_warning ("Encoding type `%s' not supported.", @@ -848,11 +867,37 @@ _set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) static CamelStream * _get_output_stream (CamelDataWrapper *data_wrapper) { - + CamelMimePart *mime_part = CAMEL_MIME_PART (data_wrapper); + CamelStream *input_stream; + CamelStream *output_stream; + /* ** FIXME : bogus bogus bogus - test test test */ + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_output_stream leaving\n"); - return camel_data_wrapper_get_input_stream (data_wrapper); + input_stream = camel_data_wrapper_get_input_stream (data_wrapper); + + if (input_stream == NULL) + return NULL; + + 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: + output_stream = camel_stream_b64_new_with_input_stream (input_stream); + camel_stream_b64_set_mode (CAMEL_STREAM_B64 (output_stream), + CAMEL_STREAM_B64_ENCODER); + return output_stream; + + case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE: + return input_stream; + } + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_output_stream leaving\n"); + return NULL; } @@ -874,6 +919,7 @@ camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding) } + /* FIXME I am not sure this is the correct way to do this. */ CamelMimePartEncodingType camel_mime_part_encoding_from_string (const gchar *string) diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c index 2b4b7d2917..5e7bb72d21 100644 --- a/camel/camel-seekable-substream.c +++ b/camel/camel-seekable-substream.c @@ -182,6 +182,14 @@ _set_bounds (CamelSeekableSubstream *seekable_substream, guint32 inf_bound, gint CAMEL_LOG_FULL_DEBUG ("CamelSeekableSubstream::_set_bounds Leaving\n"); } +static void +_reemit_parent_signal (CamelStream *parent_stream, gpointer user_data) +{ + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (user_data); + + gtk_signal_emit_by_name (GTK_OBJECT (seekable_substream), "data_available"); + +} static void @@ -201,6 +209,20 @@ _init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substre /* set the bound of the substream */ _set_bounds (seekable_substream, inf_bound, sup_bound); + + /* + * connect to the parent stream "data_available" + * stream so that we can reemit the signal on the + * seekable substream in case some data would + * be available for us + */ + gtk_signal_connect (GTK_OBJECT (parent_stream), + "data_available", + _reemit_parent_signal, + seekable_substream); + + gtk_signal_emit_by_name (GTK_OBJECT (seekable_substream), "data_available"); + } @@ -454,7 +476,7 @@ _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy) seekable_stream->cur_pos = MIN (real_offset, substream_len); } else seekable_stream->cur_pos = 0; - printf ("** set in substream %p, offset=%d\n", stream, real_offset); + printf ("** set in substream %p, offset=%lld\n", stream, real_offset); } diff --git a/camel/camel-stream-b64.c b/camel/camel-stream-b64.c new file mode 100644 index 0000000000..f43e89d982 --- /dev/null +++ b/camel/camel-stream-b64.c @@ -0,0 +1,305 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + + +/* + * + * Author : + * Bertrand Guiheneuf <bertrand@helixcode.com> + * + * Copyright 1999, 2000 HelixCode (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 <config.h> +#include "camel-stream-b64.h" + + + + +static CamelStreamClass *parent_class = NULL; + +static guchar char_to_six_bits [256] = { + 66, 66, 66, 66, 66, 66, 66, 66, /* 0 .. 7 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 8 .. 15 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 16 .. 23 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 24 .. 31 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 32 .. 39 */ + 66, 66, 66, 62, 66, 66, 66, 63, /* 40 .. 47 */ + 52, 53, 54, 55, 56, 57, 58, 59, /* 48 .. 55 */ + 60, 61, 66, 66, 66, 65, 66, 66, /* 56 .. 63 */ + 66, 0, 1, 2, 3, 4, 5, 6, /* 64 .. 71 */ + 7, 8, 9, 10, 11, 12, 13, 14, /* 72 .. 79 */ + 15, 16, 17, 18, 19, 20, 21, 22, /* 80 .. 87 */ + 23, 24, 25, 66, 66, 66, 66, 66, /* 88 .. 95 */ + 66, 26, 27, 28, 29, 30, 31, 32, /* 96 .. 103 */ + 33, 34, 35, 36, 37, 38, 39, 40, /* 104 .. 111 */ + 41, 42, 43, 44, 45, 46, 47, 48, /* 112 .. 119 */ + 49, 50, 51, 66, 66, 66, 66, 66, /* 120 .. 127 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 128 .. 135 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 136 .. 143 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 144 .. 151 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 152 .. 159 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 160 .. 167 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 168 .. 175 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 176 .. 183 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 184 .. 191 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 192 .. 199 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 200 .. 207 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 208 .. 215 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 216 .. 223 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 224 .. 231 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 232 .. 239 */ + 66, 66, 66, 66, 66, 66, 66, 66, /* 240 .. 247 */ + 66, 66, 66, 66, 66, 66, 66, 66 /* 248 .. 255 */ +}; + + +static gchar six_bits_to_char[65] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +/* Returns the class for a CamelStreamB64 */ +#define CSB64_CLASS(so) CAMEL_STREAM_B64_CLASS (GTK_OBJECT(so)->klass) + +static void init_with_input_stream__static (CamelStreamB64 *stream_b64, + CamelStream *input_stream); + +static gint read__static (CamelStream *stream, + gchar *buffer, + gint n); + +static gint read_decode__static (CamelStream *stream, + gchar *buffer, + gint n); +static gboolean eos__static (CamelStream *stream); + +static void +camel_stream_b64_class_init (CamelStreamB64Class *camel_stream_b64_class) +{ + CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_stream_b64_class); + + + parent_class = gtk_type_class (camel_stream_get_type ()); + + /* virtual method definition */ + camel_stream_b64_class->init_with_input_stream = init_with_input_stream__static; + + + /* virtual method overload */ + camel_stream_class->read = read__static; + camel_stream_class->eos = eos__static; + + /* signal definition */ + +} + +GtkType +camel_stream_b64_get_type (void) +{ + static GtkType camel_stream_b64_type = 0; + + if (!camel_stream_b64_type) { + GtkTypeInfo camel_stream_b64_info = + { + "CamelStreamB64", + sizeof (CamelStreamB64), + sizeof (CamelStreamB64Class), + (GtkClassInitFunc) camel_stream_b64_class_init, + (GtkObjectInitFunc) NULL, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + camel_stream_b64_type = gtk_type_unique (camel_stream_get_type (), &camel_stream_b64_info); + } + + return camel_stream_b64_type; +} + + +static void +reemit_available_signal__static (CamelStream *parent_stream, gpointer user_data) +{ + gtk_signal_emit_by_name (GTK_OBJECT (user_data), "data_available"); +} + +static void +init_with_input_stream__static (CamelStreamB64 *stream_b64, + CamelStream *input_stream) +{ + g_assert (stream_b64); + g_assert (input_stream); + + + + /* by default, the stream is in decode mode */ + stream_b64->mode = CAMEL_STREAM_B64_DECODER; + + stream_b64->eos = FALSE; + stream_b64->decode_status.keep = 0; + stream_b64->decode_status.state = 0; + + + stream_b64->input_stream = input_stream; + + gtk_object_ref (GTK_OBJECT (input_stream)); + + /* + * connect to the parent stream "data_available" + * stream so that we can reemit the signal on the + * seekable substream in case some data would + * be available for us + */ + gtk_signal_connect (GTK_OBJECT (input_stream), + "data_available", + reemit_available_signal__static, + stream_b64); + + + /* bootstrapping signal */ + gtk_signal_emit_by_name (GTK_OBJECT (stream_b64), "data_available"); + + +} + + + +CamelStream * +camel_stream_b64_new_with_input_stream (CamelStream *input_stream) +{ + CamelStreamB64 *stream_b64; + + stream_b64 = gtk_type_new (camel_stream_b64_get_type ()); + CSB64_CLASS (stream_b64)->init_with_input_stream (stream_b64, input_stream); + + return CAMEL_STREAM (stream_b64); +} + + + + +void +camel_stream_b64_set_mode (CamelStreamB64 *stream_b64, + CamelStreamB64Mode mode) +{ + g_assert (stream_b64); + stream_b64->mode = mode; +} + + + + +static gint +read__static (CamelStream *stream, + gchar *buffer, + gint n) +{ + CamelStreamB64 *stream_b64 = CAMEL_STREAM_B64 (stream); + + g_assert (stream); + + + if (stream_b64->mode == CAMEL_STREAM_B64_DECODER) + return read_decode__static (stream, buffer, n); + + return 0; +} + + + +static gint read_decode__static (CamelStream *stream, + gchar *buffer, + gint n) +{ + CamelStreamB64 *stream_b64 = CAMEL_STREAM_B64 (stream); + CamelStream64DecodeStatus *status; + CamelStream *input_stream; + guchar six_bits_value; + gint nb_read_in_input; + guchar c; + gint j = 0; + + g_assert (stream); + input_stream = stream_b64->input_stream; + + g_assert (input_stream); + status = &(stream_b64->decode_status); + + + /* state = (CamelStream64DecodeState *) + ((gchar *)stream_b64 + G_STRUCT_OFFSET (CamelStreamB64, decode_state)) */ + + nb_read_in_input = camel_stream_read (input_stream, &c, 1); + + while ((nb_read_in_input >0 ) && (j<n)) { + + six_bits_value = char_to_six_bits[c]; + + /* if we encounter an '=' we can assume the end of the stream + has been found */ + if (six_bits_value == 65) { + stream_b64->eos = TRUE; + break; + } + + /* test if we must ignore the character */ + if (six_bits_value != 66) { + + switch (status->state % 4){ + case 0: + status->keep = six_bits_value << 2; + break; + case 1: + buffer [j++] = status->keep | (six_bits_value >> 4); + status->keep = (six_bits_value & 0xf) << 4; + break; + case 2: + buffer [j++] = status->keep | (six_bits_value >> 2); + status->keep = (six_bits_value & 0x3) << 6; + break; + case 3: + buffer [j++] = status->keep | six_bits_value; + break; + } + + status->state = (status->state + 1) % 4; + } + + + nb_read_in_input = camel_stream_read (input_stream, &c, 1); + + } + + return j; + +} + + + + + + + +static gboolean +eos__static (CamelStream *stream) +{ + CamelStreamB64 *stream_b64 = CAMEL_STREAM_B64 (stream); + + g_assert (stream); + g_assert (stream_b64->input_stream); + + return (stream_b64->eos || camel_stream_eos (stream_b64->input_stream)); +} diff --git a/camel/camel-stream-b64.h b/camel/camel-stream-b64.h new file mode 100644 index 0000000000..2b99a0e3d9 --- /dev/null +++ b/camel/camel-stream-b64.h @@ -0,0 +1,116 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * + * Author : + * Bertrand Guiheneuf <bertrand@helixcode.com> + * + * Copyright 1999, 2000 HelixCode (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 CAMEL_STREAM_B64_H +#define CAMEL_STREAM_B64_H 1 + + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus }*/ + +#include <gtk/gtk.h> +#include "camel-stream.h" + + +#define CAMEL_STREAM_B64_TYPE (camel_stream_b64_get_type ()) +#define CAMEL_STREAM_B64(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_B64_TYPE, CamelStreamB64)) +#define CAMEL_STREAM_B64_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_B64_TYPE, CamelStreamB64Class)) +#define CAMEL_IS_STREAM_B64(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_B64_TYPE)) + + +typedef enum { + + CAMEL_STREAM_B64_DECODER, + CAMEL_STREAM_B64_ENCODER + +} CamelStreamB64Mode; + + +/* private type */ +typedef struct { + + gchar state; + gchar keep; + +} CamelStream64DecodeStatus; + + +typedef struct +{ + CamelStream parent_object; + + /* -- all these fields are private -- */ + + CamelStream *input_stream; /* the stream we get the data from before co/de-coding them */ + CamelStreamB64Mode mode; /* the stream code or decode in B64 depending on that flag */ + gboolean eos; + + /* decoding status */ + CamelStream64DecodeStatus decode_status; + +} CamelStreamB64; + + + +typedef struct { + CamelStreamClass parent_class; + + /* Virtual methods */ + void (*init_with_input_stream) (CamelStreamB64 *stream_b64, CamelStream *input_stream); + +} CamelStreamB64Class; + + + + + + +/* Standard Gtk function */ +GtkType camel_stream_b64_get_type (void); + + + + +/* public methods */ +CamelStream * camel_stream_b64_new_with_input_stream (CamelStream *input_stream); + +void camel_stream_b64_set_mode (CamelStreamB64 *stream_b64, + CamelStreamB64Mode mode); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_STREAM_B64_H */ + + + + + + diff --git a/camel/camel-stream.c b/camel/camel-stream.c index a339b23e18..77d3f4af39 100644 --- a/camel/camel-stream.c +++ b/camel/camel-stream.c @@ -38,7 +38,7 @@ static guint camel_stream_signals[LAST_SIGNAL] = { 0 }; static GtkObjectClass *parent_class = NULL; -/* Returns the class for a CamelMimeMessage */ +/* Returns the class for a CamelStream */ #define CS_CLASS(so) CAMEL_STREAM_CLASS (GTK_OBJECT(so)->klass) static void diff --git a/camel/gmime-base64.c b/camel/gmime-base64.c index a75e5c0f17..3611cc5247 100644 --- a/camel/gmime-base64.c +++ b/camel/gmime-base64.c @@ -17,7 +17,7 @@ static char *base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** - * gmime_encode_base64: + * gmime_encode_base64_to_stream: * @input: The data source to be encoded in base64 format * @output: Where to put the encoded information in. * @@ -25,7 +25,7 @@ static char *base64_alphabet = * base64 encoding and stores it on the @output CamelStream object */ void -gmime_encode_base64 (CamelStream *input, CamelStream *output) +gmime_encode_base64_to_stream (CamelStream *input, CamelStream *output) { char buffer [BSIZE]; char obuf [80]; /* Output is limited to 76 characters, rfc2045 */ @@ -83,6 +83,11 @@ gmime_encode_base64 (CamelStream *input, CamelStream *output) } + + + + + /** * gmime_decode_base64: * @input: A buffer in base64 format. diff --git a/camel/gmime-base64.h b/camel/gmime-base64.h index 58ddd58722..5dca9c0ff9 100644 --- a/camel/gmime-base64.h +++ b/camel/gmime-base64.h @@ -11,6 +11,6 @@ #include "camel-stream.h" -void gmime_encode_base64 (CamelStream *input, CamelStream *output); +void gmime_encode_base64_to_stream (CamelStream *input, CamelStream *output); #endif |