From f926f10e86aee8df632613d9c5b5022e6b8597ca Mon Sep 17 00:00:00 2001 From: bertrand Date: Wed, 16 Feb 2000 10:44:35 +0000 Subject: this routine replaces the _read_part routine and does not store the part 2000-02-15 bertrand * camel/camel-multipart.c (_localize_part): this routine replaces the _read_part routine and does not store the part in a buffer. (_set_input_stream): use the set_input_stream instead of the construct_from_stream. each bodypart is given an input stream. * camel/camel-mime-part-utils.c: include the data-wrapper-repository header. (camel_mime_part_construct_content_from_stream): use the set_input_stream instead of the construct_from_stream method. * camel/camel-seekable-substream.c (_set_bounds): cur position is set to 0 not to inf_bound. Sync svn path=/trunk/; revision=1790 --- ChangeLog | 18 +++++ camel/camel-mime-part-utils.c | 24 +++++-- camel/camel-mime-part.c | 10 +-- camel/camel-multipart.c | 137 +++++++++++++++++++++++++++++++++++++++ camel/camel-seekable-substream.c | 6 +- camel/providers/Makefile.am | 2 +- tests/test2.c | 9 +-- tests/test9.c | 2 +- 8 files changed, 188 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8344e219b..76512c0a49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2000-02-15 bertrand + + * camel/camel-multipart.c (_localize_part): + this routine replaces the _read_part routine + and does not store the part in a buffer. + (_set_input_stream): use the set_input_stream + instead of the construct_from_stream. + each bodypart is given an input stream. + + * camel/camel-mime-part-utils.c: + include the data-wrapper-repository header. + (camel_mime_part_construct_content_from_stream): + use the set_input_stream instead of the + construct_from_stream method. + + * camel/camel-seekable-substream.c (_set_bounds): + cur position is set to 0 not to inf_bound. + 2000-02-14 Miguel de Icaza * camel/providers/mbox/Makefile.am (libcamelmbox_la_LIBADD): Add diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index 463aa7cb3c..427132df75 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -30,10 +30,18 @@ #include "camel-log.h" #include "gmime-utils.h" #include "camel-simple-data-wrapper.h" - +#include "data-wrapper-repository.h" + #include "camel-mime-part-utils.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); + + void camel_mime_part_construct_headers_from_stream (CamelMimePart *mime_part, CamelStream *stream) @@ -86,6 +94,8 @@ camel_mime_part_construct_content_from_stream (CamelMimePart *mime_part, "parsing content\n"); content_type = camel_mime_part_get_content_type (mime_part); + /* here we should have a mime type */ + g_assert (content_type); if (content_type) mime_type = gmime_content_field_get_mime_type (content_type); @@ -114,11 +124,17 @@ camel_mime_part_construct_content_from_stream (CamelMimePart *mime_part, 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); - camel_data_wrapper_construct_from_stream (content_object, stream); + + /* 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, @@ -127,10 +143,10 @@ camel_mime_part_construct_content_from_stream (CamelMimePart *mime_part, gtk_object_unref (GTK_OBJECT (content_object)); - CAMEL_LOG_FULL_DEBUG ("CamelMimePartUtils::construct_from_stream " + CAMEL_LOG_FULL_DEBUG ("CamelMimePartUtils::construct_content_from_stream " "content parsed\n"); - CAMEL_LOG_FULL_DEBUG ("CamelMimePartUtils:: Leaving _construct_from_stream\n"); + CAMEL_LOG_FULL_DEBUG ("CamelMimePartUtils:: Leaving _construct_content_from_stream\n"); } diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 29e39f4386..0328ac8115 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -605,12 +605,9 @@ _get_content_object (CamelMedium *medium) CamelStream *stream; CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_content_object entering\n"); - /* - * test if there is not pending content stored in the - * temporary buffer - */ + if (!medium->content ) { - stream = camel_data_wrapper_get_input_stream (CAMEL_DATA_WRAPPER (medium)); + stream = mime_part->content_input_stream; camel_mime_part_construct_content_from_stream (mime_part, stream); @@ -795,7 +792,7 @@ _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_ -#if 0 + static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { @@ -810,7 +807,6 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) } -#endif diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c index 44ae7dfbf6..948a68e387 100644 --- a/camel/camel-multipart.c +++ b/camel/camel-multipart.c @@ -506,3 +506,140 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) g_free (end_boundary_line); CAMEL_LOG_FULL_DEBUG ("Leaving CamelMultipart::_construct_from_stream\n"); } + + + + + + + + + +/**********************/ +/* new implementation */ + + +/** + * _localize_part: localize 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, flase otherwise + **/ + +static gboolean +_localize_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; + gboolean first_line = TRUE; + guint32 last_position; + + /* Note for future enhancements */ + /* RFC 2046 precises that when parsing the content of a multipart + * element, the program should not think it will find the last boundary, + * and in particular, the message could have been damaged during + * transport, the parsing should still be OK */ + CAMEL_LOG_FULL_DEBUG ("CamelMultipart:: Entering _localize_part\n"); + + last_position = camel_seekable_stream_get_current_position (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 (stream); + new_line = gmime_read_line_from_stream (stream); + } + } + + if (new_line) g_free (new_line); + else last_part = TRUE; + + *end_position = last_position + + CAMEL_LOG_FULL_DEBUG ("CamelMultipart:: Leaving _localize_part\n"); + return (last_part); +} + + + + +static void +_set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +{ + CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper); + const gchar *boundary; + gchar *real_boundary_line; + gchar *end_boundary_line; + CamelStream *new_part_stream; + gboolean end_of_multipart; + CamelMimeBodyPart *body_part; + guint32 part_begining, part_end; + CamelSeekableSubstream *body_part_input_stream; + + CAMEL_LOG_FULL_DEBUG ("Entering CamelMultipart::_construct_from_stream\n"); + 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 = _localize_part (stream, + real_boundary_line, + end_boundary_line, + &part_end); + if (multipart->preface) g_free (multipart->preface); + + /* if ( (new_part->str)[0] != '\0') multipart->preface = g_strdup (new_part->str); */ + + /* 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 (stream); + + CAMEL_LOG_FULL_DEBUG ("CamelMultipart::construct_from_stream, detected a new part\n"); + body_part = camel_mime_body_part_new (); + + end_of_multipart = _localize_part (stream, + real_boundary_line, + end_boundary_line, + &part_end); + body_part_input_stream = + camel_seekable_substream_new_with_seekable_stream_and_bounds (seekable_stream, + part_begining, + part_end); + + camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (body_part), body_part_input_stream); + camel_multipart_add_part (multipart, body_part); + + } + + /* g_string_assign (new_part, ""); */ + /* _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); + CAMEL_LOG_FULL_DEBUG ("Leaving CamelMultipart::_construct_from_stream\n"); +} diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c index 6eabc442e7..6777eeb12d 100644 --- a/camel/camel-seekable-substream.c +++ b/camel/camel-seekable-substream.c @@ -168,11 +168,11 @@ _set_bounds (CamelSeekableSubstream *seekable_substream, guint32 inf_bound, gint /* go to the first position */ camel_seekable_stream_seek (seekable_substream->parent_stream, inf_bound, SEEK_SET); - seekable_substream->cur_pos = inf_bound; + seekable_substream->cur_pos = 0; CAMEL_LOG_FULL_DEBUG ("In CamelSeekableSubstream::_set_bounds, " - "setting inf bound to %u, " - "sup bound to %ld, current postion to %u from %u\n", + "setting inf bound to %lu, " + "sup bound to %lld, current position to %lu from %lu\n", seekable_substream->inf_bound, seekable_substream->sup_bound, seekable_substream->cur_pos, inf_bound); diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am index 2ed9c0cecc..cf43b07714 100644 --- a/camel/providers/Makefile.am +++ b/camel/providers/Makefile.am @@ -1,5 +1,5 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = mbox +SUBDIRS = mbox # this ones are disabled for the moment. # MH maildir diff --git a/tests/test2.c b/tests/test2.c index 7b69a71fd8..17fd4ffc9a 100644 --- a/tests/test2.c +++ b/tests/test2.c @@ -29,14 +29,15 @@ main (int argc, char**argv) printf ("You must create the file mail.test before running this test\n"); exit(2); } - - camel_data_wrapper_set_input_stream ( CAMEL_DATA_WRAPPER (message), input_stream); -#if 0 - camel_data_wrapper_construct_from_stream ( CAMEL_DATA_WRAPPER (message), input_stream); camel_debug_level = CAMEL_LOG_LEVEL_FULL_DEBUG; + + camel_data_wrapper_set_input_stream ( CAMEL_DATA_WRAPPER (message), input_stream); + camel_medium_get_content_object (CAMEL_MEDIUM (message)); + +#if 0 camel_stream_close (input_stream); gtk_object_unref (GTK_OBJECT (input_stream)); diff --git a/tests/test9.c b/tests/test9.c index 6776b0cc05..fa291b312a 100644 --- a/tests/test9.c +++ b/tests/test9.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3