diff options
author | bertrand <Bertrand.Guiheneuf@aful.org> | 2000-02-15 06:03:58 +0800 |
---|---|---|
committer | Bertrand Guiheneuf <bertrand@src.gnome.org> | 2000-02-15 06:03:58 +0800 |
commit | fe058b1be72112298e356343f3a8b35fd60a072b (patch) | |
tree | 0e2fe60abb27fa6070dc20f1e427b002c6db6f5a /camel | |
parent | d8efd64ed0bc53ad0a74115c1d14a700b3874013 (diff) | |
download | gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.tar gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.tar.gz gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.tar.bz2 gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.tar.lz gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.tar.xz gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.tar.zst gsoc2013-evolution-fe058b1be72112298e356343f3a8b35fd60a072b.zip |
make a blocking version of the header parser. When the fs stream uses
2000-02-14 bertrand <Bertrand.Guiheneuf@aful.org>
* camel/gmime-utils.c (get_header_array_from_stream):
make a blocking version of the header parser.
When the fs stream uses gnome-vfs, this should
be changed.
(gmime_read_line_from_stream): ditto.
2000-02-11 bertrand <Bertrand.Guiheneuf@aful.org>
* camel/camel-stream-fs.c:
everywhere, when using the cur_pos field, do it
on the CamelSeekableStream object.
(_seek): small fix.
* camel/camel-seekable-stream.c (camel_seekable_stream_seek):
s/camel_stream_seek/camel_seekable_stream_seek/g
* camel/camel-seekable-stream.h:
(struct ): added a field to store the
current position.
* camel/camel-seekable-stream.c (camel_seekable_stream_get_current_position):
New function. Allows to get the current position
of a seekable stream.
In fact much more changes, but I am lazy.
This is the begining of some major changes
in camel.
svn path=/trunk/; revision=1778
Diffstat (limited to 'camel')
-rw-r--r-- | camel/Makefile.am | 2 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 17 | ||||
-rw-r--r-- | camel/camel-mime-part.h | 51 | ||||
-rw-r--r-- | camel/camel-seekable-stream.c | 32 | ||||
-rw-r--r-- | camel/camel-seekable-stream.h | 11 | ||||
-rw-r--r-- | camel/camel-seekable-substream.c | 442 | ||||
-rw-r--r-- | camel/camel-seekable-substream.h | 94 | ||||
-rw-r--r-- | camel/camel-stream-fs.c | 30 | ||||
-rw-r--r-- | camel/camel-stream-fs.h | 1 | ||||
-rw-r--r-- | camel/camel-stream.c | 2 | ||||
-rw-r--r-- | camel/camel-stream.h | 40 | ||||
-rw-r--r-- | camel/gmime-utils.c | 36 |
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; } |