aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/camel-data-wrapper.c41
-rw-r--r--camel/camel-data-wrapper.h43
-rw-r--r--camel/camel-mime-part.c197
-rw-r--r--camel/camel-mime-part.h1
-rw-r--r--camel/camel-multipart.c2
-rw-r--r--camel/camel-seekable-substream.c83
-rw-r--r--camel/camel-seekable-substream.h15
-rw-r--r--camel/camel-stream-fs.c2
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c2
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