aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-mime-part.c17
-rw-r--r--camel/camel-mime-part.h51
-rw-r--r--camel/camel-seekable-stream.c32
-rw-r--r--camel/camel-seekable-stream.h11
-rw-r--r--camel/camel-seekable-substream.c442
-rw-r--r--camel/camel-seekable-substream.h94
-rw-r--r--camel/camel-stream-fs.c30
-rw-r--r--camel/camel-stream-fs.h1
-rw-r--r--camel/camel-stream.c2
-rw-r--r--camel/camel-stream.h40
-rw-r--r--camel/gmime-utils.c36
12 files changed, 685 insertions, 73 deletions
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 2db0ecf42c..cff67fc736 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -53,6 +53,7 @@ libcamel_la_SOURCES = \
camel-provider.c \
camel-recipient.c \
camel-seekable-stream.c \
+ camel-seekable-substream.c \
camel-service.c \
camel-session.c \
camel-store.c \
@@ -94,6 +95,7 @@ libcamelinclude_HEADERS = \
camel-provider.h \
camel-recipient.h \
camel-seekable-stream.h \
+ camel-seekable-substream.h \
camel-service.h \
camel-session.h \
camel-store.h \
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 84140f5aa7..974c770df5 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -60,8 +60,10 @@ static CamelMediumClass *parent_class=NULL;
static void _finalize (GtkObject *object);
/* from CamelDataWrapper */
-static void _write_to_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);
@@ -791,6 +793,19 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
}
+static void
+_set_input_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
+{
+ CamelMimePart *mime_part = CAMEL_MIME_PART (data_wrapper);
+
+ CAMEL_LOG_FULL_DEBUG ("CamelMimePart::construct_from_stream entering\n");
+ camel_mime_part_construct_headers_from_stream (mime_part, stream);
+
+
+
+}
+
+
const gchar *
camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding)
{
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index 573cf69576..e8ad6c1655 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -115,34 +115,35 @@ GtkType camel_mime_part_get_type (void);
/* public methods */
-void camel_mime_part_set_description (CamelMimePart *mime_part,
- const gchar *description);
-const gchar *camel_mime_part_get_description (CamelMimePart *mime_part);
-void camel_mime_part_set_disposition (CamelMimePart *mime_part,
- const gchar *disposition);
-const gchar *camel_mime_part_get_disposition (CamelMimePart *mime_part);
-void camel_mime_part_set_filename (CamelMimePart *mime_part,
- gchar *filename);
-const gchar *camel_mime_part_get_filename (CamelMimePart *mime_part);
-const gchar *camel_mime_part_get_content_id (CamelMimePart *mime_part);
-const gchar *camel_mime_part_get_content_MD5 (CamelMimePart *mime_part);
-void camel_mime_part_set_encoding (CamelMimePart *mime_part,
- CamelMimePartEncodingType type);
-CamelMimePartEncodingType camel_mime_part_get_encoding (CamelMimePart *mime_part);
-void camel_mime_part_set_content_languages (CamelMimePart *mime_part,
- GList *content_languages);
-const GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part);
-void camel_mime_part_set_header_lines (CamelMimePart *mime_part,
- GList *header_lines);
-const GList *camel_mime_part_get_header_lines (CamelMimePart *mime_part);
-
-GMimeContentField *camel_mime_part_get_content_type (CamelMimePart *mime_part);
-
-const gchar *camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding);
+void camel_mime_part_set_description (CamelMimePart *mime_part,
+ const gchar *description);
+const gchar *camel_mime_part_get_description (CamelMimePart *mime_part);
+void camel_mime_part_set_disposition (CamelMimePart *mime_part,
+ const gchar *disposition);
+const gchar *camel_mime_part_get_disposition (CamelMimePart *mime_part);
+void camel_mime_part_set_filename (CamelMimePart *mime_part,
+ gchar *filename);
+const gchar *camel_mime_part_get_filename (CamelMimePart *mime_part);
+const gchar *camel_mime_part_get_content_id (CamelMimePart *mime_part);
+const gchar *camel_mime_part_get_content_MD5 (CamelMimePart *mime_part);
+void camel_mime_part_set_encoding (CamelMimePart *mime_part,
+ CamelMimePartEncodingType type);
+CamelMimePartEncodingType camel_mime_part_get_encoding (CamelMimePart *mime_part);
+void camel_mime_part_set_content_languages (CamelMimePart *mime_part,
+ GList *content_languages);
+const GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part);
+void camel_mime_part_set_header_lines (CamelMimePart *mime_part,
+ GList *header_lines);
+const GList *camel_mime_part_get_header_lines (CamelMimePart *mime_part);
+
+GMimeContentField *camel_mime_part_get_content_type (CamelMimePart *mime_part);
+
+const gchar *camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding);
CamelMimePartEncodingType camel_mime_part_encoding_from_string (const gchar *string);
/* utility functions */
-void camel_mime_part_set_text (CamelMimePart *camel_mime_part, const gchar *text);
+void camel_mime_part_set_text (CamelMimePart *camel_mime_part,
+ const gchar *text);
#ifdef __cplusplus
diff --git a/camel/camel-seekable-stream.c b/camel/camel-seekable-stream.c
index 00cca3e369..55bbbd611a 100644
--- a/camel/camel-seekable-stream.c
+++ b/camel/camel-seekable-stream.c
@@ -78,17 +78,15 @@ camel_seekable_stream_get_type (void)
static gint
-_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy)
+_seek (CamelSeekableStream *stream,
+ gint offset,
+ CamelStreamSeekPolicy policy)
{
return -1;
}
-
-
-
-
/**
* camel_stream_seek:
* @stream: a CamelStream object.
@@ -100,7 +98,9 @@ _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy)
* Return value: new position, -1 if operation failed.
**/
gint
-camel_stream_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy)
+camel_seekable_stream_seek (CamelSeekableStream *stream,
+ gint offset,
+ CamelStreamSeekPolicy policy)
{
return CSS_CLASS (stream)->seek (stream, offset, policy);
}
@@ -108,5 +108,25 @@ camel_stream_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPoli
+/**
+ * camel_seekable_stream_get_current_position: get the position of a stream
+ * @stream: seekable stream object
+ *
+ * Get the current position of a seekable stream.
+ *
+ * Return value: the position.
+ **/
+guint32
+camel_seekable_stream_get_current_position (CamelSeekableStream *stream)
+{
+ return stream->cur_pos;
+}
+
+
+
+
+
+
+
diff --git a/camel/camel-seekable-stream.h b/camel/camel-seekable-stream.h
index 7f00edc81a..e7ab941caa 100644
--- a/camel/camel-seekable-stream.h
+++ b/camel/camel-seekable-stream.h
@@ -57,6 +57,8 @@ typedef struct
{
CamelStream parent_object;
+ guint32 cur_pos; /* current postion in the stream */
+
} CamelSeekableStream;
@@ -66,8 +68,8 @@ typedef struct {
/* Virtual methods */
gint (*seek) (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy);
-
-
+
+
} CamelSeekableStreamClass;
@@ -77,7 +79,10 @@ GtkType camel_seekable_stream_get_type (void);
/* public methods */
-gint camel_stream_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy);
+gint camel_seekable_stream_seek (CamelSeekableStream *stream,
+ gint offset,
+ CamelStreamSeekPolicy policy);
+guint32 camel_seekable_stream_get_current_position (CamelSeekableStream *stream);
#ifdef __cplusplus
diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c
new file mode 100644
index 0000000000..270bae113f
--- /dev/null
+++ b/camel/camel-seekable-substream.c
@@ -0,0 +1,442 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* camel-stream-fs.c : file system based stream */
+
+/* inspired by gnome-stream-fs.c in bonobo by Miguel de Icaza */
+/*
+ *
+ * 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-seekable-substream.h"
+#include "camel-log.h"
+
+static CamelSeekableStreamClass *parent_class=NULL;
+
+
+/* Returns the class for a CamelSeekableSubStream */
+#define CSS_CLASS(so) CAMEL_SEEKABLE_SUBSTREAM_CLASS (GTK_OBJECT(so)->klass)
+
+
+
+
+static gint _read (CamelStream *stream,
+ gchar *buffer, gint n);
+static gint _write (CamelStream *stream,
+ const gchar *buffer,
+ gint n);
+static void _flush (CamelStream *stream);
+static gint _available (CamelStream *stream);
+static gboolean _eos (CamelStream *stream);
+static void _close (CamelStream *stream);
+static gint _seek (CamelSeekableStream *stream,
+ gint offset,
+ CamelStreamSeekPolicy policy);
+
+static void _finalize (GtkObject *object);
+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);
+
+
+
+
+static void
+camel_seekable_substream_class_init (CamelSeekableSubstreamClass *camel_seekable_substream_class)
+{
+ CamelSeekableStreamClass *camel_seekable_stream_class = CAMEL_SEEKABLE_STREAM_CLASS (camel_seekable_substream_class);
+ CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_seekable_substream_class);
+ GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_seekable_substream_class);
+
+ parent_class = gtk_type_class (camel_seekable_stream_get_type ());
+
+ /* virtual method definition */
+ camel_seekable_substream_class->init_with_seekable_stream_and_bounds = _init_with_seekable_stream_and_bounds;
+
+ /* virtual method overload */
+ camel_stream_class->read = _read;
+ camel_stream_class->write = _write;
+ camel_stream_class->flush = _flush;
+ camel_stream_class->available = _available;
+ camel_stream_class->eos = _eos;
+ camel_stream_class->close = _close;
+
+ camel_seekable_stream_class->seek = _seek;
+
+ gtk_object_class->finalize = _finalize;
+ gtk_object_class->destroy = _destroy;
+
+}
+
+static void
+camel_seekable_substream_init (gpointer object, gpointer klass)
+{
+ /* does nothing */
+}
+
+
+
+
+GtkType
+camel_seekable_substream_get_type (void)
+{
+ static GtkType camel_seekable_substream_type = 0;
+
+ if (!camel_seekable_substream_type) {
+ GtkTypeInfo camel_seekable_substream_info =
+ {
+ "CamelSeekableSubstream",
+ sizeof (CamelSeekableSubstream),
+ sizeof (CamelSeekableSubstreamClass),
+ (GtkClassInitFunc) camel_seekable_substream_class_init,
+ (GtkObjectInitFunc) camel_seekable_substream_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ camel_seekable_substream_type = gtk_type_unique (camel_seekable_stream_get_type (), &camel_seekable_substream_info);
+ }
+
+ return camel_seekable_substream_type;
+}
+
+
+
+
+
+
+static void
+_destroy (GtkObject *object)
+{
+
+ CAMEL_LOG_FULL_DEBUG ("Entering CamelSeekableSubstream::destroy\n");
+
+ /* does nothing for the moment */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+
+ CAMEL_LOG_FULL_DEBUG ("Leaving CamelSeekableSubstream::destroy\n");
+}
+
+
+static void
+_finalize (GtkObject *object)
+{
+
+
+ CAMEL_LOG_FULL_DEBUG ("Entering CamelSeekableSubstream::finalize\n");
+
+ /* does nothing for the moment */
+ GTK_OBJECT_CLASS (parent_class)->finalize (object);
+ CAMEL_LOG_FULL_DEBUG ("Leaving CamelSeekableSubstream::finalize\n");
+}
+
+
+
+static void
+_set_bounds (CamelSeekableSubstream *seekable_substream, guint32 inf_bound, guint32 sup_bound)
+{
+ CAMEL_LOG_FULL_DEBUG ("CamelSeekableSubstream::_set_bounds entering\n");
+
+ g_assert (seekable_substream);
+ g_assert (seekable_substream->parent_stream);
+
+ /* store the bounds */
+ seekable_substream->inf_bound = inf_bound;
+ seekable_substream->sup_bound = sup_bound;
+
+ /* go to the first position */
+ camel_seekable_stream_seek (seekable_substream->parent_stream, inf_bound, SEEK_SET);
+
+ seekable_substream->cur_pos = inf_bound;
+
+ CAMEL_LOG_FULL_DEBUG ("In CamelSeekableSubstream::_set_bounds, "
+ "setting inf bound to %u, "
+ "sup bound to %ld, current postion to %u from %u\n",
+ seekable_substream->inf_bound, seekable_substream->sup_bound,
+ seekable_substream->cur_pos, inf_bound);
+
+ CAMEL_LOG_FULL_DEBUG ("CamelSeekableSubstream::_set_bounds Leaving\n");
+}
+
+
+
+static void
+_init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream,
+ CamelSeekableStream *parent_stream,
+ guint32 inf_bound,
+ guint32 sup_bound)
+{
+ /* sanity checks */
+ g_assert (seekable_substream);
+ g_assert (!seekable_substream->parent_stream);
+ g_assert (parent_stream);
+
+ /* store the parent stream */
+ seekable_substream->parent_stream = parent_stream;
+
+ /* set the bound of the substream */
+ _set_bounds (seekable_substream, inf_bound, sup_bound);
+}
+
+
+void
+camel_seekable_substream_init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream,
+ CamelSeekableStream *parent_stream,
+ guint32 inf_bound,
+ guint32 sup_bound)
+{
+
+ CSS_CLASS (seekable_substream)->init_with_seekable_stream_and_bounds (seekable_substream,
+ parent_stream,
+ inf_bound,
+ sup_bound);
+
+}
+
+
+
+
+
+/**
+ * _read: read bytes from a stream
+ * @stream: stream
+ * @buffer: buffer where bytes are stored
+ * @n: max number of bytes to read
+ *
+ *
+ *
+ * Return value: number of bytes actually read.
+ **/
+static gint
+_read (CamelStream *stream, gchar *buffer, gint n)
+{
+ CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
+ CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream);
+ gint v;
+ gint nb_to_read;
+ guint32 parent_stream_current_position;
+ guint32 position_in_parent;
+
+ g_assert (stream);
+ g_assert (seekable_substream->parent_stream);
+ g_assert (seekable_substream->open);
+
+
+
+ /*
+ we are doing something quite infefficient :
+
+ each time we want to read a block, we store
+ the parent stream position so that we can
+ change it, and restore it before returning
+
+ This may change. I don't know yet.
+ It may be useless to reseek every time
+ and is incompatible with buffering.
+ */
+
+ parent_stream_current_position =
+ camel_seekable_stream_get_current_position (seekable_substream->parent_stream);
+
+ /* compute the position in the parent stream */
+ position_in_parent =
+ 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);
+
+
+
+ /* compute how much byte should be read */
+ nb_to_read =
+ MIN (seekable_substream->sup_bound - position_in_parent, n);
+
+
+ /* Read the data */
+ if (nb_to_read >0 )
+ v = camel_stream_read ( CAMEL_STREAM (seekable_substream->parent_stream),
+ buffer,
+ nb_to_read);
+ else
+ v = 0;
+
+ /* if the return value is negative, an error occured,
+ we must do something FIXME : handle exception */
+ if (v<0)
+ CAMEL_LOG_FULL_DEBUG ("CamelSeekableSubstream::read v=%d\n", v);
+ else
+ seekable_stream->cur_pos += v;
+
+
+ /* restore the parent position */
+ camel_seekable_stream_seek (seekable_substream->parent_stream,
+ parent_stream_current_position,
+ CAMEL_STREAM_SET);
+
+
+ /* return the number of bytes read */
+ return v;
+}
+
+
+/**
+ * _write: write bytes to a stream
+ * @stream: the stream
+ * @buffer: byte buffer
+ * @n: number of bytes to write
+ *
+ *
+ *
+ * Return value: the number of bytes actually written
+ * in the stream.
+ **/
+static gint
+_write (CamelStream *stream, const gchar *buffer, gint n)
+{
+ /* NOT VALID ON SEEKABLE SUBSTREAM */
+ g_warning ("CamelSeekableSubstream:: seekable substream don't have a write method\n");
+ CAMEL_LOG_WARNING ( "CamelSeekableSubstream:: seekable substream don't have a write method\n");
+ return -1;
+}
+
+
+
+/**
+ * _flush: flush pending changes
+ * @stream: the stream
+ *
+ *
+ **/
+static void
+_flush (CamelStream *stream)
+{
+ /* NOT VALID ON SEEKABLE SUBSTREAM */
+ g_warning ("CamelSeekableSubstream:: seekable substream don't have a flush method\n");
+ CAMEL_LOG_WARNING ( "CamelSeekableSubstream:: seekable substream don't have a flush method\n");
+}
+
+
+
+/**
+ * _available: return the number of bytes available for reading
+ * @stream: the stream
+ *
+ * Return the number of bytes available without blocking.
+ *
+ * Return value: the number of bytes available
+ **/
+static gint
+_available (CamelStream *stream)
+{
+ g_warning ("not implemented\n");
+ return -1;
+}
+
+
+/**
+ * _eos: test if there are bytes left to read
+ * @stream: the stream
+ *
+ *
+ *
+ * Return value: true if all stream has been read
+ **/
+static gboolean
+_eos (CamelStream *stream)
+{
+ CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream);
+ CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
+ guint32 substream_len;
+
+
+ g_assert (stream);
+ g_assert (seekable_substream->open);
+
+ substream_len = seekable_substream->sup_bound - seekable_substream->inf_bound;
+
+ return ( seekable_stream->cur_pos > substream_len);
+}
+
+
+/**
+ * _close: close a stream
+ * @stream: the stream
+ *
+ *
+ **/
+static void
+_close (CamelStream *stream)
+{
+ CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream);
+
+ g_assert (stream);
+ seekable_substream->open = FALSE;
+}
+
+
+static gint
+_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy)
+{
+ CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream);
+ CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
+ gint64 real_offset;
+ guint32 substream_len;
+
+
+ substream_len = seekable_substream->sup_bound - seekable_substream->inf_bound;
+
+ switch (policy) {
+
+ case CAMEL_STREAM_SET:
+ real_offset = offset;
+
+ break;
+
+ case CAMEL_STREAM_CUR:
+ real_offset = seekable_stream->cur_pos + offset;
+
+ break;
+
+ case CAMEL_STREAM_END:
+ real_offset = substream_len - offset;
+
+ break;
+
+ default:
+ return -1;
+ }
+
+ 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
new file mode 100644
index 0000000000..f7ef19d353
--- /dev/null
+++ b/camel/camel-seekable-substream.h
@@ -0,0 +1,94 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* camel-seekable-substream.h : stream */
+
+/*
+ *
+ * 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_SEEKABLE_SUBSTREAM_H
+#define CAMEL_SEEKABLE_SUBSTREAM_H 1
+
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus }*/
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include "camel-seekable-stream.h"
+
+
+
+#define CAMEL_SEEKABLE_SUBSTREAM_TYPE (camel_seekable_substream_get_type ())
+#define CAMEL_SEEKABLE_SUBSTREAM(obj) (GTK_CHECK_CAST((obj), CAMEL_SEEKABLE_SUBSTREAM_TYPE, CamelSeekableSubstream))
+#define CAMEL_SEEKABLE_SUBSTREAM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SEEKABLE_SUBSTREAM_TYPE, CamelSeekableSubstreamClass))
+#define CAMEL_IS_SEEKABLE_SUBSTREAM(o) (GTK_CHECK_TYPE((o), CAMEL_SEEKABLE_SUBSTREAM_TYPE))
+
+
+
+
+typedef struct
+{
+ CamelSeekableStream parent_object;
+
+ /* --**-- Private fields --**-- */
+ 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 */
+ gboolean open;
+
+} CamelSeekableSubstream;
+
+
+
+typedef struct {
+ CamelSeekableStreamClass parent_class;
+
+ /* Virtual methods */
+ void (*init_with_seekable_stream_and_bounds) (CamelSeekableSubstream *seekable_substream,
+ CamelSeekableStream *parent_stream,
+ guint32 inf_bound,
+ guint32 sup_bound);
+
+} CamelSeekableSubstreamClass;
+
+
+
+/* Standard Gtk function */
+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);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CAMEL_SEEKABLE_SUBSTREAM_H */
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c
index 26dde90803..e816f88b6b 100644
--- a/camel/camel-stream-fs.c
+++ b/camel/camel-stream-fs.c
@@ -168,13 +168,13 @@ _set_bounds (CamelStreamFs *stream_fs, guint32 inf_bound, guint32 sup_bound)
/* go to the first position */
lseek (stream_fs->fd, inf_bound, SEEK_SET);
- stream_fs->cur_pos = inf_bound;
+ CAMEL_SEEKABLE_STREAM (stream_fs)->cur_pos = inf_bound;
CAMEL_LOG_FULL_DEBUG ("In CamelStreamFs::_set_bounds, "
"setting inf bound to %u, "
"sup bound to %ld, current postion to %u from %u\n",
stream_fs->inf_bound, stream_fs->sup_bound,
- stream_fs->cur_pos, inf_bound);
+ CAMEL_SEEKABLE_STREAM (stream_fs)->cur_pos, inf_bound);
}
@@ -187,7 +187,7 @@ _init_with_fd (CamelStreamFs *stream_fs, int fd)
stream_fs->fd = fd;
stream_fs->inf_bound = 0;
stream_fs->sup_bound = -1;
- stream_fs->cur_pos = 0;
+ CAMEL_SEEKABLE_STREAM (stream_fs)->cur_pos = 0;
}
@@ -219,12 +219,12 @@ _init_with_name (CamelStreamFs *stream_fs, const gchar *name, CamelStreamFsMode
if (mode & CAMEL_STREAM_FS_READ){
if (mode & CAMEL_STREAM_FS_WRITE)
- flags = O_RDWR | O_CREAT;
+ flags = O_RDWR | O_CREAT | O_NONBLOCK;
else
- flags = O_RDONLY;
+ flags = O_RDONLY | O_NONBLOCK;
} else {
if (mode & CAMEL_STREAM_FS_WRITE)
- flags = O_WRONLY | O_CREAT;
+ flags = O_WRONLY | O_CREAT | O_NONBLOCK;
else
return;
}
@@ -245,7 +245,7 @@ _init_with_name (CamelStreamFs *stream_fs, const gchar *name, CamelStreamFsMode
stream_fs->name = g_strdup (name);
CSFS_CLASS (stream_fs)->init_with_fd (stream_fs, fd);
-
+
}
@@ -260,7 +260,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,
- stream_fs->cur_pos);
+ CAMEL_SEEKABLE_STREAM (stream)->cur_pos);
}
@@ -345,7 +345,7 @@ _read (CamelStream *stream, gchar *buffer, gint n)
gint nb_to_read;
if (stream_fs->sup_bound != -1)
- nb_to_read = MIN (stream_fs->sup_bound - stream_fs->cur_pos, n);
+ nb_to_read = MIN (stream_fs->sup_bound - CAMEL_SEEKABLE_STREAM (stream)->cur_pos, n);
else
nb_to_read = n;
@@ -355,7 +355,7 @@ _read (CamelStream *stream, gchar *buffer, gint n)
if (v<0)
CAMEL_LOG_FULL_DEBUG ("CamelStreamFs::read v=%d\n", v);
else
- stream_fs->cur_pos += v;
+ CAMEL_SEEKABLE_STREAM (stream)->cur_pos += v;
return v;
}
@@ -384,7 +384,7 @@ _write (CamelStream *stream, const gchar *buffer, gint n)
CAMEL_LOG_FULL_DEBUG ( "CamelStreamFs:: entering write. n=%d\n", n);
if (stream_fs->sup_bound != -1)
- nb_to_write = MIN (stream_fs->sup_bound - stream_fs->cur_pos, n);
+ nb_to_write = MIN (stream_fs->sup_bound - CAMEL_SEEKABLE_STREAM (stream)->cur_pos, n);
else
nb_to_write = n;
@@ -400,7 +400,7 @@ _write (CamelStream *stream, const gchar *buffer, gint n)
#endif
if (v>0)
- stream_fs->cur_pos += v;
+ CAMEL_SEEKABLE_STREAM (stream)->cur_pos += v;
return v;
@@ -484,10 +484,10 @@ _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy)
break;
case CAMEL_STREAM_CUR:
- if ((stream_fs->sup_bound == -1) && ((stream_fs->cur_pos + offset) > stream_fs->sup_bound)) {
+ if ((stream_fs->sup_bound != -1) && ((CAMEL_SEEKABLE_STREAM (stream)->cur_pos + offset) > stream_fs->sup_bound)) {
real_offset = stream_fs->sup_bound;
whence = SEEK_SET;
- } else if ((stream_fs->cur_pos + offset) < stream_fs->inf_bound) {
+ } else if ((CAMEL_SEEKABLE_STREAM (stream)->cur_pos + offset) < stream_fs->inf_bound) {
real_offset = stream_fs->inf_bound;
whence = SEEK_SET;
} else
@@ -515,7 +515,7 @@ _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy)
return_position = lseek (stream_fs->fd, real_offset, whence) - stream_fs->inf_bound;
- stream_fs->cur_pos = return_position;
+ CAMEL_SEEKABLE_STREAM (stream)->cur_pos = return_position;
return return_position;
}
diff --git a/camel/camel-stream-fs.h b/camel/camel-stream-fs.h
index 4910abbd5f..2e7dfd946f 100644
--- a/camel/camel-stream-fs.h
+++ b/camel/camel-stream-fs.h
@@ -57,7 +57,6 @@ typedef struct
gchar *name; /* name of the underlying file */
gint fd; /* file descriptor on the underlying file */
- guint32 cur_pos; /* current postion in the stream */
guint32 inf_bound; /* first valid position */
gint32 sup_bound; /* last valid position, -1 means, no sup bound */
diff --git a/camel/camel-stream.c b/camel/camel-stream.c
index 0a18ed1ee5..bad7f6811c 100644
--- a/camel/camel-stream.c
+++ b/camel/camel-stream.c
@@ -160,7 +160,7 @@ camel_stream_flush (CamelStream *stream)
*
* Return value: the number of bytes available.
**/
-gint
+gboolean
camel_stream_available (CamelStream *stream)
{
return CS_CLASS (stream)->available (stream);
diff --git a/camel/camel-stream.h b/camel/camel-stream.h
index d0327971af..0496e13d7f 100644
--- a/camel/camel-stream.h
+++ b/camel/camel-stream.h
@@ -57,35 +57,49 @@ typedef struct {
void (*data_available) (CamelStream *stream); /* default "data_available" signal handler */
- gint (*read) (CamelStream *stream, gchar *buffer, gint n);
- gint (*write) (CamelStream *stream, const gchar *buffer, gint n);
- void (*flush) (CamelStream *stream);
- gint (*available) (CamelStream *stream);
- gboolean (*eos) (CamelStream *stream);
- void (*close) (CamelStream *stream);
+ gint (*read) (CamelStream *stream, gchar *buffer, gint n);
+ gint (*write) (CamelStream *stream, const gchar *buffer, gint n);
+ void (*flush) (CamelStream *stream);
+ gint (*available) (CamelStream *stream);
+ gboolean (*eos) (CamelStream *stream);
+ void (*close) (CamelStream *stream);
} CamelStreamClass;
+
+
+
/* Standard Gtk function */
GtkType camel_stream_get_type (void);
+
+
/* public methods */
-gint camel_stream_read (CamelStream *stream, gchar *buffer, gint n);
-gint camel_stream_write (CamelStream *stream, const gchar *buffer, gint n);
-void camel_stream_flush (CamelStream *stream);
-gint camel_stream_available (CamelStream *stream);
-gboolean camel_stream_eos (CamelStream *stream);
-void camel_stream_close (CamelStream *stream);
+gint camel_stream_read (CamelStream *stream, gchar *buffer, gint n);
+gint camel_stream_write (CamelStream *stream, const gchar *buffer, gint n);
+void camel_stream_flush (CamelStream *stream);
+gboolean camel_stream_available (CamelStream *stream);
+gboolean camel_stream_eos (CamelStream *stream);
+void camel_stream_close (CamelStream *stream);
+
+
+
/* utility macros and funcs */
#define camel_stream_write_string(stream, string) camel_stream_write ((stream), (string), strlen (string))
-void camel_stream_write_strings (CamelStream *stream, ... );
+void camel_stream_write_strings (CamelStream *stream, ... );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CAMEL_STREAM_H */
+
+
+
+
+
+
diff --git a/camel/gmime-utils.c b/camel/gmime-utils.c
index 421808a4d4..1b1f1aa1e1 100644
--- a/camel/gmime-utils.c
+++ b/camel/gmime-utils.c
@@ -160,7 +160,11 @@ _store_header_pair_from_string (GArray *header_array, gchar *header_line)
-
+/*
+ this is a blocking version of the
+ header parsing. Need to change when
+ fs streams are non blocking
+*/
GArray *
get_header_array_from_stream (CamelStream *stream)
{
@@ -177,8 +181,6 @@ get_header_array_from_stream (CamelStream *stream)
gboolean end_of_file = FALSE;
GString *header_line=NULL;
- gchar *str_header_line;
-
GArray *header_array;
@@ -215,23 +217,29 @@ get_header_array_from_stream (CamelStream *stream)
default:
if (!crlf) header_line = g_string_append_c (header_line, next_char);
else end_of_header_line = TRUE;
+
}
} else {
- end_of_file=TRUE;
- end_of_header_line = TRUE;
+
+ if (nb_char_read <0) {
+ end_of_file=TRUE;
+ end_of_header_line = TRUE;
+
+ }
}
+
/* if we have read a whole header line, we have also read
the first character of the next line to be sure the
crlf was not followed by a space or a tab char */
if (!end_of_header_line) nb_char_read = camel_stream_read (stream, &next_char, 1);
-
+
} while ( !end_of_header_line );
if ( strlen(header_line->str) ) {
/* str_header_line = g_strdup (header_line->str); */
_store_header_pair_from_string (header_array, header_line->str);
}
g_string_free (header_line, FALSE);
-
+
} while ( (!end_of_headers) && (!end_of_file) );
CAMEL_LOG_FULL_DEBUG ( "gmime-utils:: Leaving get_header_table_from_stream\n");
@@ -239,6 +247,7 @@ get_header_array_from_stream (CamelStream *stream)
}
+
gchar *
gmime_read_line_from_stream (CamelStream *stream)
{
@@ -252,7 +261,9 @@ gmime_read_line_from_stream (CamelStream *stream)
new_line = g_string_new ("");
do {
nb_char_read = camel_stream_read (stream, &next_char, 1);
+
if (nb_char_read>0) {
+
switch (next_char) {
case '\n':
end_of_line = TRUE;
@@ -260,13 +271,22 @@ gmime_read_line_from_stream (CamelStream *stream)
break;
default:
g_string_append_c (new_line, next_char);
+
}
- } else end_of_stream = TRUE;
+ } else {
+
+ if (nb_char_read <0)
+ end_of_stream = TRUE;
+
+ }
} while (!end_of_line && !end_of_stream);
+
if (!end_of_stream)
result = g_strdup (new_line->str);
else result=NULL;
+
g_string_free (new_line, TRUE);
+
return result;
}