diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/camel-data-wrapper.c | 41 | ||||
-rw-r--r-- | camel/camel-data-wrapper.h | 43 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 197 | ||||
-rw-r--r-- | camel/camel-mime-part.h | 1 | ||||
-rw-r--r-- | camel/camel-multipart.c | 2 | ||||
-rw-r--r-- | camel/camel-seekable-substream.c | 83 | ||||
-rw-r--r-- | camel/camel-seekable-substream.h | 15 | ||||
-rw-r--r-- | camel/camel-stream-fs.c | 2 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 2 |
9 files changed, 251 insertions, 135 deletions
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c index 0489f184c2..1ec70c6b37 100644 --- a/camel/camel-data-wrapper.c +++ b/camel/camel-data-wrapper.c @@ -66,6 +66,11 @@ camel_data_wrapper_class_init (CamelDataWrapperClass *camel_data_wrapper_class) camel_data_wrapper_class->set_mime_type_field = _set_mime_type_field; camel_data_wrapper_class->get_stream = _get_stream; + 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; + /* virtual method overload */ gtk_object_class->finalize = _finalize; } @@ -138,6 +143,17 @@ _set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) } +void +camel_data_wrapper_set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +{ + g_assert (data_wrapper); + CDW_CLASS(data_wrapper)->set_input_stream (data_wrapper, stream); +} + + + + + static CamelStream * _get_input_stream (CamelDataWrapper *data_wrapper) { @@ -145,6 +161,15 @@ _get_input_stream (CamelDataWrapper *data_wrapper) return (data_wrapper->input_stream); } +CamelStream * +camel_data_wrapper_get_input_stream (CamelDataWrapper *data_wrapper) +{ + g_assert (data_wrapper); + return CDW_CLASS(data_wrapper)->get_input_stream (data_wrapper); +} + + + static void _set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) @@ -153,6 +178,15 @@ _set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) data_wrapper->output_stream = stream; } +void +camel_data_wrapper_set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +{ + g_assert (data_wrapper); + CDW_CLASS(data_wrapper)->set_output_stream (data_wrapper, stream); +} + + + static CamelStream * _get_output_stream (CamelDataWrapper *data_wrapper) @@ -161,7 +195,12 @@ _get_output_stream (CamelDataWrapper *data_wrapper) return (data_wrapper->output_stream); } - +CamelStream * +camel_data_wrapper_get_output_stream (CamelDataWrapper *data_wrapper) +{ + g_assert (data_wrapper); + return CDW_CLASS(data_wrapper)->get_output_stream (data_wrapper); +} diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h index d4e86b277d..7c16cc65bd 100644 --- a/camel/camel-data-wrapper.h +++ b/camel/camel-data-wrapper.h @@ -64,21 +64,27 @@ typedef struct { GtkObjectClass parent_class; /* Virtual methods */ - void (*set_input_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream); + 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); + void (*set_output_stream) (CamelDataWrapper *data_wrapper, + CamelStream *stream); CamelStream * (*get_output_stream) (CamelDataWrapper *data_wrapper); - void (*set_mime_type) (CamelDataWrapper *data_wrapper, const gchar * mime_type); + void (*set_mime_type) (CamelDataWrapper *data_wrapper, + const gchar * mime_type); gchar * (*get_mime_type) (CamelDataWrapper *data_wrapper); GMimeContentField * (*get_mime_type_field) (CamelDataWrapper *data_wrapper); - void (*set_mime_type_field) (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type_field); + void (*set_mime_type_field) (CamelDataWrapper *data_wrapper, + GMimeContentField *mime_type_field); /* deprecated method */ CamelStream * (*get_stream) (CamelDataWrapper *data_wrapper); - void (*write_to_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream); - void (*construct_from_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream); + void (*write_to_stream) (CamelDataWrapper *data_wrapper, + CamelStream *stream); + void (*construct_from_stream) (CamelDataWrapper *data_wrapper, + CamelStream *stream); } CamelDataWrapperClass; @@ -90,17 +96,28 @@ GtkType camel_data_wrapper_get_type (void); /* public methods */ +void 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); +GMimeContentField * camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper); +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_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); -GMimeContentField *camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper); -void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type); /* deprecated methods. Left until the new parser scheme is ok */ -CamelStream *camel_data_wrapper_get_stream (CamelDataWrapper *data_wrapper); -void camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); +CamelStream * camel_data_wrapper_get_stream (CamelDataWrapper *data_wrapper); +void camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, + CamelStream *stream); #ifdef __cplusplus } diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 974c770df5..29e39f4386 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -24,6 +24,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ + + + + #include <config.h> #include <string.h> #include "camel-mime-part.h" @@ -35,6 +39,10 @@ #include "camel-simple-data-wrapper.h" #include "hash-table-utils.h" #include "camel-stream-mem.h" +#include "camel-mime-part-utils.h" +#include "gmime-base64.h" +#include "camel-seekable-substream.h" + typedef enum { HEADER_UNKNOWN, @@ -57,41 +65,60 @@ static CamelMediumClass *parent_class=NULL; #define CMP_CLASS(so) CAMEL_MIME_PART_CLASS (GTK_OBJECT(so)->klass) /* from GtkObject */ -static void _finalize (GtkObject *object); +static void _finalize (GtkObject *object); /* from CamelDataWrapper */ -static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); -static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); -static void _set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); +static void _write_to_stream (CamelDataWrapper *data_wrapper, + CamelStream *stream); +static void _construct_from_stream (CamelDataWrapper *data_wrapper, + CamelStream *stream); +static void _set_input_stream (CamelDataWrapper *data_wrapper, + CamelStream *stream); /* from CamelMedia */ -static void _add_header (CamelMedium *medium, gchar *header_name, gchar *header_value); - -static void _set_content_object (CamelMedium *medium, CamelDataWrapper *content); -static CamelDataWrapper *_get_content_object (CamelMedium *medium); - -/* CamelMimePart methods */ -static void _set_description (CamelMimePart *mime_part, const gchar *description); -static const gchar *_get_description (CamelMimePart *mime_part); -static void _set_disposition (CamelMimePart *mime_part, const gchar *disposition); -static const gchar *_get_disposition (CamelMimePart *mime_part); -static void _set_filename (CamelMimePart *mime_part, gchar *filename); -static const gchar *_get_filename (CamelMimePart *mime_part); -static void _set_content_id (CamelMimePart *mime_part, gchar *content_id); -static const gchar *_get_content_id (CamelMimePart *mime_part); -static void _set_content_MD5 (CamelMimePart *mime_part, gchar *content_MD5); -static const gchar *_get_content_MD5 (CamelMimePart *mime_part); -static void _set_encoding (CamelMimePart *mime_part, CamelMimePartEncodingType encoding); -static CamelMimePartEncodingType _get_encoding (CamelMimePart *mime_part); -static void _set_content_languages (CamelMimePart *mime_part, GList *content_languages); -static const GList *_get_content_languages (CamelMimePart *mime_part); -static void _set_header_lines (CamelMimePart *mime_part, GList *header_lines); -static const GList *_get_header_lines (CamelMimePart *mime_part); -static void _set_content_type (CamelMimePart *mime_part, const gchar *content_type); -static GMimeContentField *_get_content_type (CamelMimePart *mime_part); - -static gboolean _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_value); +static void _add_header (CamelMedium *medium, + gchar *header_name, + gchar *header_value); + +static void _set_content_object (CamelMedium *medium, + CamelDataWrapper *content); +static CamelDataWrapper *_get_content_object (CamelMedium *medium); + + + +/* from CamelMimePart */ +static void _set_description (CamelMimePart *mime_part, + const gchar *description); +static const gchar * _get_description (CamelMimePart *mime_part); +static void _set_disposition (CamelMimePart *mime_part, + const gchar *disposition); +static const gchar * _get_disposition (CamelMimePart *mime_part); +static void _set_filename (CamelMimePart *mime_part, + gchar *filename); +static const gchar * _get_filename (CamelMimePart *mime_part); +static void _set_content_id (CamelMimePart *mime_part, + gchar *content_id); +static const gchar * _get_content_id (CamelMimePart *mime_part); +static void _set_content_MD5 (CamelMimePart *mime_part, + gchar *content_MD5); +static const gchar * _get_content_MD5 (CamelMimePart *mime_part); +static void _set_encoding (CamelMimePart *mime_part, + CamelMimePartEncodingType encoding); +static CamelMimePartEncodingType _get_encoding (CamelMimePart *mime_part); +static void _set_content_languages (CamelMimePart *mime_part, + GList *content_languages); +static const GList * _get_content_languages (CamelMimePart *mime_part); +static void _set_header_lines (CamelMimePart *mime_part, + GList *header_lines); +static const GList * _get_header_lines (CamelMimePart *mime_part); +static void _set_content_type (CamelMimePart *mime_part, + const gchar *content_type); +static GMimeContentField *_get_content_type (CamelMimePart *mime_part); + +static gboolean _parse_header_pair (CamelMimePart *mime_part, + gchar *header_name, + gchar *header_value); @@ -122,36 +149,37 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) _init_header_name_table(); /* virtual method definition */ - camel_mime_part_class->set_description = _set_description; - camel_mime_part_class->get_description = _get_description; - camel_mime_part_class->set_disposition = _set_disposition; - camel_mime_part_class->get_disposition = _get_disposition; - camel_mime_part_class->set_filename = _set_filename; - camel_mime_part_class->get_filename = _get_filename; - camel_mime_part_class->set_content_id = _set_content_id; - camel_mime_part_class->get_content_id = _get_content_id; - camel_mime_part_class->set_content_MD5 =_set_content_MD5; - camel_mime_part_class->get_content_MD5 = _get_content_MD5; - camel_mime_part_class->set_encoding = _set_encoding; - camel_mime_part_class->get_encoding = _get_encoding; - camel_mime_part_class->set_content_languages = _set_content_languages; - camel_mime_part_class->get_content_languages = _get_content_languages; - camel_mime_part_class->set_header_lines =_set_header_lines; - camel_mime_part_class->get_header_lines =_get_header_lines; - camel_mime_part_class->set_content_type = _set_content_type; - camel_mime_part_class->get_content_type = _get_content_type; + camel_mime_part_class->set_description = _set_description; + camel_mime_part_class->get_description = _get_description; + camel_mime_part_class->set_disposition = _set_disposition; + camel_mime_part_class->get_disposition = _get_disposition; + camel_mime_part_class->set_filename = _set_filename; + camel_mime_part_class->get_filename = _get_filename; + camel_mime_part_class->set_content_id = _set_content_id; + camel_mime_part_class->get_content_id = _get_content_id; + camel_mime_part_class->set_content_MD5 = _set_content_MD5; + camel_mime_part_class->get_content_MD5 = _get_content_MD5; + camel_mime_part_class->set_encoding = _set_encoding; + camel_mime_part_class->get_encoding = _get_encoding; + camel_mime_part_class->set_content_languages = _set_content_languages; + camel_mime_part_class->get_content_languages = _get_content_languages; + camel_mime_part_class->set_header_lines = _set_header_lines; + camel_mime_part_class->get_header_lines = _get_header_lines; + camel_mime_part_class->set_content_type = _set_content_type; + camel_mime_part_class->get_content_type = _get_content_type; - camel_mime_part_class->parse_header_pair = _parse_header_pair; + camel_mime_part_class->parse_header_pair = _parse_header_pair; /* virtual method overload */ - camel_medium_class->add_header = _add_header; - camel_medium_class->set_content_object = _set_content_object; - camel_medium_class->get_content_object = _get_content_object; + camel_medium_class->add_header = _add_header; + camel_medium_class->set_content_object = _set_content_object; + camel_medium_class->get_content_object = _get_content_object; - camel_data_wrapper_class->write_to_stream = _write_to_stream; + camel_data_wrapper_class->write_to_stream = _write_to_stream; camel_data_wrapper_class->construct_from_stream = _construct_from_stream; + camel_data_wrapper_class->set_input_stream = _set_input_stream; - gtk_object_class->finalize = _finalize; + gtk_object_class->finalize = _finalize; } static void @@ -159,15 +187,15 @@ camel_mime_part_init (gpointer object, gpointer klass) { CamelMimePart *camel_mime_part = CAMEL_MIME_PART (object); - camel_mime_part->content_type = gmime_content_field_new (NULL, NULL); - camel_mime_part->description = NULL; - camel_mime_part->disposition = NULL; - camel_mime_part->content_id = NULL; - camel_mime_part->content_MD5 = NULL; - camel_mime_part->content_languages = NULL; - camel_mime_part->encoding = CAMEL_MIME_PART_ENCODING_DEFAULT; - camel_mime_part->filename = NULL; - camel_mime_part->header_lines = NULL; + camel_mime_part->content_type = gmime_content_field_new (NULL, NULL); + camel_mime_part->description = NULL; + camel_mime_part->disposition = NULL; + camel_mime_part->content_id = NULL; + camel_mime_part->content_MD5 = NULL; + camel_mime_part->content_languages = NULL; + camel_mime_part->encoding = CAMEL_MIME_PART_ENCODING_DEFAULT; + camel_mime_part->filename = NULL; + camel_mime_part->header_lines = NULL; camel_mime_part->temp_message_buffer = NULL; @@ -210,8 +238,6 @@ _finalize (GtkObject *object) CAMEL_LOG_FULL_DEBUG ("Entering CamelMimePart::finalize\n"); - - g_free (mime_part->description); gmime_content_field_unref (mime_part->disposition); g_free (mime_part->content_id); @@ -234,9 +260,6 @@ static void _add_header (CamelMedium *medium, gchar *header_name, gchar *header_value) { CamelMimePart *mime_part = CAMEL_MIME_PART (medium); - gboolean header_exists; - gchar *old_header_name; - gchar *old_header_value; /* Try to parse the header pair. If it corresponds to something */ /* known, the job is done in the parsing routine. If not, */ @@ -586,18 +609,14 @@ _get_content_object (CamelMedium *medium) * test if there is not pending content stored in the * temporary buffer */ - if ((!medium->content ) && (mime_part->temp_message_buffer)) { - stream = camel_stream_mem_new_with_buffer (mime_part->temp_message_buffer, - CAMEL_STREAM_MEM_READ); + if (!medium->content ) { + stream = camel_data_wrapper_get_input_stream (CAMEL_DATA_WRAPPER (medium)); + camel_mime_part_construct_content_from_stream (mime_part, stream); - /* - * Beware : this will destroy the temp buffer as well - */ - gtk_object_unref (GTK_OBJECT (stream)); - mime_part->temp_message_buffer = 0; + } else { CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_content_object part has a pointer " - "to a content object as well as a temp buffer\n"); + "to a content object\n"); } CAMEL_LOG_FULL_DEBUG ("CamelMimePart::get_content_object leaving\n"); @@ -624,9 +643,6 @@ _write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream) { CamelMedium *medium = CAMEL_MEDIUM (mime_part); CamelStream *wrapper_stream; - guint buffer_size; - gchar *buffer; - gchar *encoded_buffer; CamelDataWrapper *content = medium->content; CAMEL_LOG_FULL_DEBUG ( "Entering CamelMimePart::_write_content_to_stream\n"); @@ -778,6 +794,8 @@ _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_ } + +#if 0 static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { @@ -792,17 +810,32 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) } +#endif + + static void _set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimePart *mime_part = CAMEL_MIME_PART (data_wrapper); + CamelSeekableStream *seekable_stream; + guint32 content_stream_inf_bound; + CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream entering\n"); - camel_mime_part_construct_headers_from_stream (mime_part, stream); + g_assert (CAMEL_IS_SEEKABLE_STREAM (stream)); + seekable_stream = CAMEL_SEEKABLE_STREAM (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); + mime_part->content_input_stream = + camel_seekable_substream_new_with_seekable_stream_and_bounds (seekable_stream, + content_stream_inf_bound, + -1); + } diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index e8ad6c1655..4b48ce1c0c 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -74,6 +74,7 @@ typedef struct GByteArray *temp_message_buffer; GMimeContentField *content_type; + CamelStream *content_input_stream; } CamelMimePart; diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c index b30f8590b0..44ae7dfbf6 100644 --- a/camel/camel-multipart.c +++ b/camel/camel-multipart.c @@ -487,7 +487,7 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) body_part = camel_mime_body_part_new (); end_of_multipart = _read_part ( new_part_stream, stream, real_boundary_line, end_boundary_line); - camel_stream_seek (new_part_stream, 0, CAMEL_STREAM_SET); + camel_seekable_stream_seek (new_part_stream, 0, CAMEL_STREAM_SET); camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (body_part), new_part_stream); camel_multipart_add_part (multipart, body_part); gtk_object_destroy (GTK_OBJECT (new_part_stream)); diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c index 270bae113f..6eabc442e7 100644 --- a/camel/camel-seekable-substream.c +++ b/camel/camel-seekable-substream.c @@ -56,7 +56,7 @@ static void _destroy (GtkObject *object); static void _init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent_stream, guint32 inf_bound, - guint32 sup_bound); + gint64 sup_bound); @@ -154,7 +154,7 @@ _finalize (GtkObject *object) static void -_set_bounds (CamelSeekableSubstream *seekable_substream, guint32 inf_bound, guint32 sup_bound) +_set_bounds (CamelSeekableSubstream *seekable_substream, guint32 inf_bound, gint64 sup_bound) { CAMEL_LOG_FULL_DEBUG ("CamelSeekableSubstream::_set_bounds entering\n"); @@ -185,7 +185,7 @@ static void _init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent_stream, guint32 inf_bound, - guint32 sup_bound) + gint64 sup_bound) { /* sanity checks */ g_assert (seekable_substream); @@ -200,18 +200,23 @@ _init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substre } -void -camel_seekable_substream_init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream, - CamelSeekableStream *parent_stream, - guint32 inf_bound, - guint32 sup_bound) + +CamelSeekableSubstream * +camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStream *parent_stream, + guint32 inf_bound, + gint64 sup_bound) { - + CamelSeekableSubstream *seekable_substream; + + /* create the seekable substream */ + seekable_substream = gtk_type_new (camel_seekable_substream_get_type ()); + + /* initialize it */ CSS_CLASS (seekable_substream)->init_with_seekable_stream_and_bounds (seekable_substream, parent_stream, inf_bound, sup_bound); - + return seekable_substream; } @@ -264,15 +269,19 @@ _read (CamelStream *stream, gchar *buffer, gint n) seekable_stream->cur_pos + seekable_substream->inf_bound; /* go to our position in the parent stream */ - camel_seekable_stream_seek (seekable_substream->parent_stream, - position_in_parent, - CAMEL_STREAM_SET); + if (parent_stream_current_position != position_in_parent) + camel_seekable_stream_seek (seekable_substream->parent_stream, + position_in_parent, + CAMEL_STREAM_SET); /* compute how much byte should be read */ - nb_to_read = - MIN (seekable_substream->sup_bound - position_in_parent, n); + if (seekable_substream->sup_bound != -1) + nb_to_read = + MIN (seekable_substream->sup_bound - position_in_parent, n); + else + nb_to_read = n; /* Read the data */ @@ -291,12 +300,14 @@ _read (CamelStream *stream, gchar *buffer, gint n) seekable_stream->cur_pos += v; +#if 0 /* restore the parent position */ camel_seekable_stream_seek (seekable_substream->parent_stream, parent_stream_current_position, CAMEL_STREAM_SET); +#endif /* return the number of bytes read */ return v; } @@ -370,14 +381,19 @@ _eos (CamelStream *stream) CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream); CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); guint32 substream_len; - - + gboolean eos; + g_assert (stream); g_assert (seekable_substream->open); - substream_len = seekable_substream->sup_bound - seekable_substream->inf_bound; + if (seekable_substream->sup_bound != -1) { + substream_len = seekable_substream->sup_bound - seekable_substream->inf_bound; + eos = ( seekable_stream->cur_pos > substream_len); + } else { + eos = camel_stream_eos (CAMEL_STREAM (seekable_substream->parent_stream)); + } - return ( seekable_stream->cur_pos > substream_len); + return eos; } @@ -402,12 +418,13 @@ _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy) { CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream); CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); - gint64 real_offset; + gint64 real_offset = 0; guint32 substream_len; - + guint32 parent_pos; + gboolean seek_done = FALSE; substream_len = seekable_substream->sup_bound - seekable_substream->inf_bound; - + switch (policy) { case CAMEL_STREAM_SET: @@ -421,19 +438,27 @@ _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy) break; case CAMEL_STREAM_END: - real_offset = substream_len - offset; + if (seekable_substream->sup_bound != -1) + real_offset = substream_len - offset; + else { + parent_pos = camel_seekable_stream_seek (seekable_substream->parent_stream, + offset, + CAMEL_STREAM_END); + seekable_stream->cur_pos = parent_pos - seekable_substream->inf_bound; + seek_done = TRUE; + } break; default: return -1; } - - if (real_offset > 0) { - seekable_stream->cur_pos = MIN (real_offset, substream_len); - } else - seekable_stream->cur_pos = 0; - + if (!seek_done) { + if (real_offset > 0) { + seekable_stream->cur_pos = MIN (real_offset, substream_len); + } else + seekable_stream->cur_pos = 0; + } return seekable_stream->cur_pos; diff --git a/camel/camel-seekable-substream.h b/camel/camel-seekable-substream.h index f7ef19d353..93c4bf7d97 100644 --- a/camel/camel-seekable-substream.h +++ b/camel/camel-seekable-substream.h @@ -56,7 +56,7 @@ typedef struct CamelSeekableStream *parent_stream; /* the stream this substream uses */ guint32 cur_pos; /* current postion in the stream */ guint32 inf_bound; /* first valid position */ - guint32 sup_bound; /* first invalid position */ + gint64 sup_bound; /* first invalid position */ gboolean open; } CamelSeekableSubstream; @@ -70,7 +70,7 @@ typedef struct { void (*init_with_seekable_stream_and_bounds) (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent_stream, guint32 inf_bound, - guint32 sup_bound); + gint64 sup_bound); } CamelSeekableSubstreamClass; @@ -81,11 +81,12 @@ GtkType camel_seekable_substream_get_type (void); /* public methods */ -void -camel_seekable_substream_init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream, - CamelSeekableStream *parent_stream, - guint32 inf_bound, - guint32 sup_bound); + +/* obtain a new seekable substream */ +CamelSeekableSubstream * +camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStream *parent_stream, + guint32 inf_bound, + gint64 sup_bound); #ifdef __cplusplus } diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index e9771d8245..6c50282e33 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -261,7 +261,7 @@ _init_with_name_and_bounds (CamelStreamFs *stream_fs, const gchar *name, CamelSt "setting inf bound to %u, " "sup bound to %ld, current postion to %u\n", stream_fs->inf_bound, stream_fs->sup_bound, - CAMEL_SEEKABLE_STREAM (stream)->cur_pos); + CAMEL_SEEKABLE_STREAM (stream_fs)->cur_pos); } diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 09c08d967a..64d559c00a 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -167,7 +167,7 @@ camel_mbox_folder_get_type (void) - + static void |