From c93a2e37f54523d409556426d4179761c8838b9f Mon Sep 17 00:00:00 2001 From: NotZed Date: Wed, 26 Apr 2000 10:35:25 +0000 Subject: Big cleanup of camel-stream-*, got rid of 3 classes, improved the interfaces, and fixed at least one problem (end of stream never happening in certain cases). Things that can fail now have a way of saying they failed too. So much for taking ANZAC day off to get drunk! 2000-04-26 NotZed * camel-seekable-substream.c (stream_seek): Changed to have absolute seek semantics, not relative to the bounds. * camel-seekable-stream.c (reset): When we reset, seek to the start of the bound, if there is one. (stream_tell): Make tell virtual. * camel-stream-filter.c (do_available): Removed. * camel-stream-buffer.c: Remove leading _'s from static functions. (stream_read): Renamed from read(). Fancy that conflicting! (my boo!) Others too. * providers/pop3/camel-pop3-folder.c (get_message_by_number): Changed to stream_mem interface. * providers/mbox/camel-mbox-folder.c (_get_message_by_uid): Fixed for streamfs interface changes, and implement a failure case. (_append_message): Changed for fs stream interface change. * camel-multipart.c (print_part): Iterate rahter than callback. I hate glists's interface (hence, move this to write_to_stream). (write_to_stream): Return an error (yuck, this is a royal PITA to do with the stream write interface). * camel-mime-message.c: Removed leading _ from static names. * camel-mime-part.h: construct_from_parser() now returns an error code. * camel-mime-part-utils.c (camel_mime_part_construct_content_from_parser): Changed to use a camel-data-wrapper instead of a camel-simple-data-wrapper (no change needed elsewhere?). (simple_data_wrapper_construct_from_parser): Fixes for stream-mem interface changes. * camel-simple-data-wrapper.[ch], camel-simple-data-wrapper-stream.[ch], camel-stream-data-wrapper.[ch], removed. Fixed including of these files. * camel-mime-part.c (camel_mime_part_set_text): Remove the use of the camel-simple-data-wrapper-stream, just use a mem stream. (write_to_stream): Renamed from my_* (construct_from_stream): Return an error on error. * camel-stream-mem.c (camel_stream_mem_new*): Remove mode parameter. * camel-stream-mem.h (enum CamelStreamMemMode): Removed. It wasn't used at all. * camel-data-wrapper.h: Add camel_data_wrapper_new() to create these. (write_to_stream, construct_from_stream): Return an error indicator for success. Fixed all methods to match (ICK). * Makefile.am (libcamel_la_SOURCES): Remove camel-simple-data-wrapper.c, camel-simple-data-wrapper-stream.c, camel-stream-data-wrapper.c. Obsoleted by code re-use! * camel-data-wrapper.c (construct_from_stream): Change the default implementation to just set the output stream == construction stream. Well, this lets me get rid of both simple-data-wrapper and stream-data-wrapper (unused anyway), and simple-data-wrapper-stream in one hit. CamelDataWrapper is now also a concrete class. (write_to_stream): Use camel_stream_write_to_stream() to calculate/return values (and save code). Include for obvious reasons. * camel-stream.c (eos): Provide a default implementation of .eos(). (camel_stream_write_to_stream): Make it return an error code on error. (camel_stream_printf): Changed to return the number of bytes written/error. (camel_stream_available): Removed. * camel-stream-fs.h (enum CamelStreamFsMode): Removed. Changed to use unix modes and so forth (wasn't used for anything but new file creation and didn't work well either). * camel-stream-fs.c: Removed leading _'s for names. And removed some virtual method 'documentation'. (destroy): Dont try and close a closed/error fd. Only report error if close returns -1. Moved all the code to finalise(), and killed this function. (init_with_fd): Properly setup the seek offset, if it is a valid and seekable file descriptor. (init_with_fd_and_bounds): Use off_t for bounds, set bounds on the seekable stream. (init_with_name): Return error codes. (init_with_name_and_bounds): Ditto. (camel_stream_fs_new_with_name): REturn NULL object if it failed. (camel_stream_fs_new_with_name_and_bounds): Return NULL object on failure. Changed with_name* api's to take unix open style args and flags. (read): The bounded stream bounds checking seemed off, simplified code a bit. (write): Implement bounds checking for writing, the comment was wrong, it could make sense to bound writing. Cleaned up a little. (available): Gone. (eos): Removed. Use CamelStream's implementation now. (close): Reset the fd to -1, provide a warning for bad usage. (seek): Cleaned up. Changed the behaviour a little, the returned offset is the absolute position in the file, even in bounded streams. (seek): Seek from end mirrors lseek() behaviour (reverse seeking). 2000-04-25 NotZed * camel-stream-fs.h (struct _CamelStreamFs): Moved bounds and eof indicator to other parent classes. * camel-stream.c (camel_stream_printf): New utility function. Obvious use. * camel-stream-mem.c: Removed leading _'s from static func's. (camel_stream_mem_new_with_byte_array): Fixed for api changes, set the owner for the byte array to us. : Removed A bunch of gtk doc stuff for static (implementation) functions. (available): Removed. (write): Fixed the write implementation so that seek() works on a seekable memory stream, as expected. Seeking past the end of the buffer has unix semantics (filling with 0). (available): Removed. (write): Implement seekable stream bounded stream. (read): Implement seekable stream bounded stream. (close): Dont free the stream_mem if we're not the owner. (seek): Allow to seek beyond the end of memory area, implement bounds checking. (seek): Set errno on bad policy. * camel-stream-mem.h (struct _CamelStreamMem): Changed position to off_t. (new_with_buffer): Changed len to be a size_t. (set_buffer, set_byte_array): New interface functions. (struct _CamelStreamMem): Removed position, it is stored in the superclass. * camel-stream.h: Removed some of the seemingly random whitespace. Removed the available method (its not impelemented/useful enough). * camel-seekable-substream.c (init_with_seekable_stream_and_bounds): Remove the data_available stuff, it hasn't been properly implemented/finished, and may never work (unfortunately *sigh). (reemit_parent_signal): Removed part of the above change. (set_bounds): Removed (moved to seekable-stream). : Fixed up some of the generally unreadable indenting (sorry, wrapping at 80 characters with camels_really_long_function_names() just_doesnt_work_very_well_does_it(). (available): Removed. (stream_seek): Fixup for object changes. Make sure we return -1 if the parent stream can't seek. * camel-seekable-stream.c (ccamel_seekable_stream_set_bounds): New function to bound any seekable stream. : Removed _'s. (camel_seekable_stream_class_init): Implement an init function, to setup the stream bounds to unbound. * camel-seekable-stream.h (CamelSeekableStreamClass): New virtual method set_bounds for seekable streams. (CAMEL_STREAM_UNBOUND): New define for no bound. * camel-seekable-substream.h (struct _CamelSeekableSubstream): Removed sup_bound and inf_bound, moved to CamelSeekableStream (and renamed, and changed to off_t's). (new_with_seekable_stream_and_bounds): Use off_t as the bounds. (CamelSeekableSubstreamClass): Uh, why was the intialiser virtual? Removed. * camel-seekable-stream.[ch] (CamelSeekableStreamClass): Changed seek to accept an off_t as the offset. (struct _CamelSeekableStream): Renamed cur_pos to position and changed it to an off_t type. (enum CamelStreamSeekPolicy): Set to match the SEEK_* constants from lseek(). (get_current_position): Renamed to tell(). * camel-stream-buffer.h: Commented out set_vbuf - never implemented. svn path=/trunk/; revision=2624 --- camel/ChangeLog | 187 ++++++++++++ camel/Makefile.am | 6 - camel/camel-data-wrapper.c | 67 ++--- camel/camel-data-wrapper.h | 11 +- camel/camel-medium.c | 1 - camel/camel-mime-message.c | 108 +++---- camel/camel-mime-parser.c | 1 + camel/camel-mime-part-utils.c | 10 +- camel/camel-mime-part.c | 97 ++++--- camel/camel-mime-part.h | 16 +- camel/camel-multipart.c | 68 ++--- camel/camel-seekable-stream.c | 89 ++++-- camel/camel-seekable-stream.h | 34 ++- camel/camel-seekable-substream.c | 231 +++++---------- camel/camel-seekable-substream.h | 23 +- camel/camel-simple-data-wrapper-stream.c | 280 ------------------ camel/camel-simple-data-wrapper-stream.h | 69 ----- camel/camel-simple-data-wrapper.c | 194 ------------- camel/camel-simple-data-wrapper.h | 82 ------ camel/camel-stream-buffer.c | 81 +++--- camel/camel-stream-buffer.h | 3 +- camel/camel-stream-data-wrapper.c | 199 ------------- camel/camel-stream-data-wrapper.h | 71 ----- camel/camel-stream-filter.c | 13 - camel/camel-stream-fs.c | 464 +++++++++++------------------- camel/camel-stream-fs.h | 53 ++-- camel/camel-stream-mem.c | 237 +++++++-------- camel/camel-stream-mem.h | 39 +-- camel/camel-stream.c | 75 +++-- camel/camel-stream.h | 27 +- camel/camel.h | 2 - camel/providers/mbox/camel-mbox-folder.c | 15 +- camel/providers/mbox/camel-mbox-summary.c | 2 +- camel/providers/pop3/camel-pop3-folder.c | 3 +- 34 files changed, 935 insertions(+), 1923 deletions(-) delete mode 100644 camel/camel-simple-data-wrapper-stream.c delete mode 100644 camel/camel-simple-data-wrapper-stream.h delete mode 100644 camel/camel-simple-data-wrapper.c delete mode 100644 camel/camel-simple-data-wrapper.h delete mode 100644 camel/camel-stream-data-wrapper.c delete mode 100644 camel/camel-stream-data-wrapper.h (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index bd6efd3d04..654781d18b 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,190 @@ +2000-04-26 NotZed + + * camel-seekable-substream.c (stream_seek): Changed to have + absolute seek semantics, not relative to the bounds. + + * camel-seekable-stream.c (reset): When we reset, seek to the + start of the bound, if there is one. + (stream_tell): Make tell virtual. + + * camel-stream-filter.c (do_available): Removed. + + * camel-stream-buffer.c: Remove leading _'s from static functions. + (stream_read): Renamed from read(). Fancy that conflicting! (my + boo!) Others too. + + * providers/pop3/camel-pop3-folder.c (get_message_by_number): + Changed to stream_mem interface. + + * providers/mbox/camel-mbox-folder.c (_get_message_by_uid): Fixed + for streamfs interface changes, and implement a failure case. + (_append_message): Changed for fs stream interface change. + + * camel-multipart.c (print_part): Iterate rahter than callback. I + hate glists's interface (hence, move this to write_to_stream). + (write_to_stream): Return an error (yuck, this is a royal PITA to + do with the stream write interface). + + * camel-mime-message.c: Removed leading _ from static names. + + * camel-mime-part.h: construct_from_parser() now returns an error + code. + + * camel-mime-part-utils.c + (camel_mime_part_construct_content_from_parser): Changed to use a + camel-data-wrapper instead of a camel-simple-data-wrapper (no + change needed elsewhere?). + (simple_data_wrapper_construct_from_parser): Fixes for stream-mem + interface changes. + + * camel-simple-data-wrapper.[ch], + camel-simple-data-wrapper-stream.[ch], + camel-stream-data-wrapper.[ch], removed. Fixed including of these + files. + + * camel-mime-part.c (camel_mime_part_set_text): Remove the use of + the camel-simple-data-wrapper-stream, just use a mem stream. + (write_to_stream): Renamed from my_* + (construct_from_stream): Return an error on error. + + * camel-stream-mem.c (camel_stream_mem_new*): Remove mode + parameter. + + * camel-stream-mem.h (enum CamelStreamMemMode): Removed. It + wasn't used at all. + + * camel-data-wrapper.h: Add camel_data_wrapper_new() to create + these. + (write_to_stream, construct_from_stream): Return an error + indicator for success. Fixed all methods to match (ICK). + + * Makefile.am (libcamel_la_SOURCES): Remove + camel-simple-data-wrapper.c, camel-simple-data-wrapper-stream.c, + camel-stream-data-wrapper.c. Obsoleted by code re-use! + + * camel-data-wrapper.c (construct_from_stream): Change the default + implementation to just set the output stream == construction + stream. Well, this lets me get rid of both simple-data-wrapper + and stream-data-wrapper (unused anyway), and + simple-data-wrapper-stream in one hit. CamelDataWrapper is now + also a concrete class. + (write_to_stream): Use camel_stream_write_to_stream() to + calculate/return values (and save code). + Include for obvious reasons. + + * camel-stream.c (eos): Provide a default implementation of .eos(). + (camel_stream_write_to_stream): Make it return an error code on + error. + (camel_stream_printf): Changed to return the number of bytes + written/error. + (camel_stream_available): Removed. + + * camel-stream-fs.h (enum CamelStreamFsMode): Removed. Changed to + use unix modes and so forth (wasn't used for anything but new file + creation and didn't work well either). + + * camel-stream-fs.c: Removed leading _'s for names. And removed + some virtual method 'documentation'. + (destroy): Dont try and close a closed/error fd. Only report + error if close returns -1. Moved all the code to finalise(), and + killed this function. + (init_with_fd): Properly setup the seek offset, if it is a + valid and seekable file descriptor. + (init_with_fd_and_bounds): Use off_t for bounds, set bounds on the + seekable stream. + (init_with_name): Return error codes. + (init_with_name_and_bounds): Ditto. + (camel_stream_fs_new_with_name): REturn NULL object if it failed. + (camel_stream_fs_new_with_name_and_bounds): Return NULL object on + failure. Changed with_name* api's to take unix open style args + and flags. + (read): The bounded stream bounds checking seemed off, simplified + code a bit. + (write): Implement bounds checking for writing, the comment was + wrong, it could make sense to bound writing. Cleaned up a little. + (available): Gone. + (eos): Removed. Use CamelStream's implementation now. + (close): Reset the fd to -1, provide a warning for bad usage. + (seek): Cleaned up. Changed the behaviour a little, the returned + offset is the absolute position in the file, even in bounded + streams. + (seek): Seek from end mirrors lseek() behaviour (reverse seeking). + +2000-04-25 NotZed + + * camel-stream-fs.h (struct _CamelStreamFs): Moved bounds and eof + indicator to other parent classes. + + * camel-stream.c (camel_stream_printf): New utility + function. Obvious use. + + * camel-stream-mem.c: Removed leading _'s from static func's. + (camel_stream_mem_new_with_byte_array): Fixed for api changes, set + the owner for the byte array to us. + : Removed A bunch of gtk doc stuff for static (implementation) functions. + (available): Removed. + (write): Fixed the write implementation so that seek() works on a + seekable memory stream, as expected. Seeking past the end of the + buffer has unix semantics (filling with 0). + (available): Removed. + (write): Implement seekable stream bounded stream. + (read): Implement seekable stream bounded stream. + (close): Dont free the stream_mem if we're not the owner. + (seek): Allow to seek beyond the end of memory area, + implement bounds checking. + (seek): Set errno on bad policy. + + * camel-stream-mem.h (struct _CamelStreamMem): Changed position to off_t. + (new_with_buffer): Changed len to be a size_t. + (set_buffer, set_byte_array): New interface functions. + (struct _CamelStreamMem): Removed position, it is stored in the + superclass. + + * camel-stream.h: Removed some of the seemingly random + whitespace. Removed the available method (its not + impelemented/useful enough). + + * camel-seekable-substream.c + (init_with_seekable_stream_and_bounds): Remove the data_available + stuff, it hasn't been properly implemented/finished, and may never + work (unfortunately *sigh). + (reemit_parent_signal): Removed part of the above change. + (set_bounds): Removed (moved to seekable-stream). + : Fixed up some of the generally unreadable indenting (sorry, + wrapping at 80 characters with + camels_really_long_function_names() + just_doesnt_work_very_well_does_it(). + (available): Removed. + (stream_seek): Fixup for object changes. Make sure we return -1 + if the parent stream can't seek. + + * camel-seekable-stream.c (ccamel_seekable_stream_set_bounds): New + function to bound any seekable stream. + : Removed _'s. + (camel_seekable_stream_class_init): Implement an init function, to + setup the stream bounds to unbound. + + * camel-seekable-stream.h (CamelSeekableStreamClass): New virtual + method set_bounds for seekable streams. + (CAMEL_STREAM_UNBOUND): New define for no bound. + + * camel-seekable-substream.h (struct _CamelSeekableSubstream): + Removed sup_bound and inf_bound, moved to CamelSeekableStream (and + renamed, and changed to off_t's). + (new_with_seekable_stream_and_bounds): Use off_t as the bounds. + (CamelSeekableSubstreamClass): Uh, why was the intialiser virtual? + Removed. + + * camel-seekable-stream.[ch] (CamelSeekableStreamClass): Changed seek + to accept an off_t as the offset. + (struct _CamelSeekableStream): Renamed cur_pos to position and + changed it to an off_t type. + (enum CamelStreamSeekPolicy): Set to match the SEEK_* constants + from lseek(). + (get_current_position): Renamed to tell(). + + * camel-stream-buffer.h: Commented out set_vbuf - never implemented. + 2000-04-25 Dan Winship * camel-stream-buffer.c (_eos): only return TRUE if the parent is diff --git a/camel/Makefile.am b/camel/Makefile.am index 4fd033a315..a395c13037 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -35,9 +35,6 @@ libcamel_la_SOURCES = \ camel.c \ camel-data-wrapper.c \ camel-exception.c \ - camel-simple-data-wrapper.c \ - camel-simple-data-wrapper-stream.c \ - camel-stream-data-wrapper.c \ camel-folder.c \ camel-folder-utils.c \ camel-medium.c \ @@ -82,9 +79,6 @@ libcamelinclude_HEADERS = \ camel.h \ camel-data-wrapper.h \ camel-exception.h \ - camel-simple-data-wrapper.h \ - camel-simple-data-wrapper-stream.h \ - camel-stream-data-wrapper.h \ camel-folder.h \ camel-folder-utils.h \ camel-mime-body-part.h \ diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c index 777d0361d9..e3edba1034 100644 --- a/camel/camel-data-wrapper.c +++ b/camel/camel-data-wrapper.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-data-wrapper.c : Abstract class for a data_wrapper */ -/** THIS IS MOSTLY AN ABSTRACT CLASS THAT SHOULD HAVE BEEN AN - INTERFACE. **/ - /* * * Authors: Bertrand Guiheneuf @@ -28,6 +25,8 @@ #include #include "camel-data-wrapper.h" +#include + #define d(x) static GtkObjectClass *parent_class = NULL; @@ -40,9 +39,9 @@ static void set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static CamelStream *get_output_stream (CamelDataWrapper *data_wrapper); -static void construct_from_stream(CamelDataWrapper *, CamelStream *); -static void write_to_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); +static int construct_from_stream(CamelDataWrapper *, CamelStream *); +static int write_to_stream (CamelDataWrapper *data_wrapper, + CamelStream *stream); static void set_mime_type (CamelDataWrapper *data_wrapper, const gchar *mime_type); static gchar *get_mime_type (CamelDataWrapper *data_wrapper); @@ -127,6 +126,20 @@ finalize (GtkObject *object) parent_class->finalize (object); } +/** + * camel_data_wrapper_new: + * + * Create a new camel data wrapper object. + * + * Return value: + **/ +CamelDataWrapper * +camel_data_wrapper_new(void) +{ + return gtk_type_new(camel_data_wrapper_get_type()); +} + + static void set_output_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { @@ -192,12 +205,9 @@ camel_data_wrapper_get_output_stream (CamelDataWrapper *data_wrapper) } -static void +static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { - gchar tmp_buf[4096]; - gint nb_read; - gint nb_written; CamelStream *output_stream; d(printf("data_wrapper::write_to_stream\n")); @@ -205,21 +215,15 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) output_stream = camel_data_wrapper_get_output_stream (data_wrapper); if (!output_stream) { g_warning("write to stream with no stream"); - return; + errno = EBADF; + return -1; } camel_stream_reset (output_stream); - while (!camel_stream_eos (output_stream)) { - nb_read = camel_stream_read (output_stream, tmp_buf, 4096); - d(printf("copying %d bytes\n", nb_read)); - nb_written = 0; - while (nb_written < nb_read) - nb_written += camel_stream_write (stream, tmp_buf + nb_written, nb_read - nb_written); - } + return camel_stream_write_to_stream(output_stream, stream); } - /** * camel_data_wrapper_write_to_stream: * @data_wrapper: a data wrapper @@ -230,24 +234,24 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) * equivalent data wrapper object later by passing this stream to * camel_data_construct_from_stream(). * - * Of course, this operation might fail, and of course, there's no - * way for you to find out about it. + * Returns the number of bytes written, and -1 for error. **/ -void +int camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { - g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper)); - g_return_if_fail (CAMEL_IS_STREAM (stream)); + g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1); + g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); - CDW_CLASS (data_wrapper)->write_to_stream (data_wrapper, stream); + return CDW_CLASS (data_wrapper)->write_to_stream (data_wrapper, stream); } -static void +static int construct_from_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) { - g_warning("Construct from stream unimplemented for class: %s", gtk_type_name(((GtkObject *)data_wrapper)->klass->type)); + camel_data_wrapper_set_output_stream (data_wrapper, stream); + return 0; } /** @@ -260,14 +264,14 @@ construct_from_stream(CamelDataWrapper *data_wrapper, * * This could fail, but you can't know if it did. **/ -void +int camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { - g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper)); - g_return_if_fail (CAMEL_IS_STREAM (stream)); + g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1); + g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); - CDW_CLASS (data_wrapper)->construct_from_stream (data_wrapper, stream); + return CDW_CLASS (data_wrapper)->construct_from_stream (data_wrapper, stream); } @@ -341,7 +345,6 @@ camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper) return CDW_CLASS (data_wrapper)->get_mime_type_field (data_wrapper); } - /** * camel_data_wrapper_set_mime_type_field: * @data_wrapper: a data wrapper diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h index 29e7be0f1e..0a3e0363a2 100644 --- a/camel/camel-data-wrapper.h +++ b/camel/camel-data-wrapper.h @@ -57,7 +57,6 @@ struct _CamelDataWrapper typedef struct { - GtkObjectClass parent_class; /* Virtual methods */ @@ -72,12 +71,11 @@ typedef struct { void (*set_mime_type_field) (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type_field); - void (*write_to_stream) (CamelDataWrapper *data_wrapper, + int (*write_to_stream) (CamelDataWrapper *data_wrapper, CamelStream *stream); - void (*construct_from_stream) (CamelDataWrapper *data_wrapper, + int (*construct_from_stream) (CamelDataWrapper *data_wrapper, CamelStream *); - } CamelDataWrapperClass; @@ -87,8 +85,9 @@ GtkType camel_data_wrapper_get_type (void); /* public methods */ +CamelDataWrapper *camel_data_wrapper_new (void); -void camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper, +int 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); @@ -101,7 +100,7 @@ void camel_data_wrapper_set_output_stream (CamelDataWrappe CamelStream *stream); CamelStream * camel_data_wrapper_get_output_stream (CamelDataWrapper *data_wrapper); -void camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, +int camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); #ifdef __cplusplus diff --git a/camel/camel-medium.c b/camel/camel-medium.c index 142d146ffe..fca8117630 100644 --- a/camel/camel-medium.c +++ b/camel/camel-medium.c @@ -30,7 +30,6 @@ #include "string-utils.h" #include "gmime-utils.h" #include "hash-table-utils.h" -#include "camel-simple-data-wrapper.h" #define d(x) diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index fb034d36cf..60a518acec 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -55,20 +55,20 @@ static gchar *reply_to_str; static gchar *subject_str; static gchar *from_str; -static void _add_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type, const gchar *recipient); -static void _remove_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type, const gchar *recipient); -static const GList *_get_recipients (CamelMimeMessage *mime_message, const gchar *recipient_type); -static void _set_flag (CamelMimeMessage *mime_message, const gchar *flag, gboolean value); -static gboolean _get_flag (CamelMimeMessage *mime_message, const gchar *flag); -static GList *_get_flag_list (CamelMimeMessage *mime_message); -static void _set_message_number (CamelMimeMessage *mime_message, guint number); -static guint _get_message_number (CamelMimeMessage *mime_message); -static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); -static void _finalize (GtkObject *object); +static void add_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type, const gchar *recipient); +static void remove_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type, const gchar *recipient); +static const GList *get_recipients (CamelMimeMessage *mime_message, const gchar *recipient_type); +static void set_flag (CamelMimeMessage *mime_message, const gchar *flag, gboolean value); +static gboolean get_flag (CamelMimeMessage *mime_message, const gchar *flag); +static GList *get_flag_list (CamelMimeMessage *mime_message); +static void set_message_number (CamelMimeMessage *mime_message, guint number); +static guint get_message_number (CamelMimeMessage *mime_message); +static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); +static void finalize (GtkObject *object); static void add_header (CamelMedium *medium, const char *header_name, const void *header_value); static void set_header (CamelMedium *medium, const char *header_name, const void *header_value); static void remove_header (CamelMedium *medium, const char *header_name); -static void construct_from_parser (CamelMimePart *, CamelMimeParser *); +static int construct_from_parser (CamelMimePart *, CamelMimeParser *); /* Returns the class for a CamelMimeMessage */ #define CMM_CLASS(so) CAMEL_MIME_MESSAGE_CLASS (GTK_OBJECT(so)->klass) @@ -77,7 +77,7 @@ static void construct_from_parser (CamelMimePart *, CamelMimeParser *); static void -_init_header_name_table() +init_header_name_table() { header_name_table = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (header_name_table, "From", (gpointer)HEADER_FROM); @@ -98,7 +98,7 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) CamelMediumClass *camel_medium_class = CAMEL_MEDIUM_CLASS (camel_mime_message_class); parent_class = gtk_type_class (camel_mime_part_get_type ()); - _init_header_name_table(); + init_header_name_table(); received_date_str = ""; sent_date_str = ""; @@ -107,17 +107,17 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) from_str = "From"; /* virtual method definition */ - camel_mime_message_class->add_recipient = _add_recipient; - camel_mime_message_class->remove_recipient = _remove_recipient; - camel_mime_message_class->get_recipients = _get_recipients; - camel_mime_message_class->set_flag = _set_flag; - camel_mime_message_class->get_flag = _get_flag; - camel_mime_message_class->get_flag_list = _get_flag_list; - camel_mime_message_class->set_message_number = _set_message_number; - camel_mime_message_class->get_message_number = _get_message_number; + camel_mime_message_class->add_recipient = add_recipient; + camel_mime_message_class->remove_recipient = remove_recipient; + camel_mime_message_class->get_recipients = get_recipients; + camel_mime_message_class->set_flag = set_flag; + camel_mime_message_class->get_flag = get_flag; + camel_mime_message_class->get_flag_list = get_flag_list; + camel_mime_message_class->set_message_number = set_message_number; + camel_mime_message_class->get_message_number = get_message_number; /* virtual method overload */ - camel_data_wrapper_class->write_to_stream = _write_to_stream; + camel_data_wrapper_class->write_to_stream = write_to_stream; camel_medium_class->add_header = add_header; camel_medium_class->set_header = set_header; @@ -125,7 +125,7 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) camel_mime_part_class->construct_from_parser = construct_from_parser; - gtk_object_class->finalize = _finalize; + gtk_object_class->finalize = finalize; } @@ -178,7 +178,7 @@ camel_mime_message_get_type (void) static void -_finalize (GtkObject *object) +finalize (GtkObject *object) { CamelMimeMessage *message = CAMEL_MIME_MESSAGE (object); @@ -322,7 +322,7 @@ camel_mime_message_get_from (CamelMimeMessage *mime_message) /* **** */ static void -_add_recipient (CamelMimeMessage *mime_message, +add_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type, const gchar *recipient) { @@ -343,7 +343,7 @@ camel_mime_message_add_recipient (CamelMimeMessage *mime_message, static void -_remove_recipient (CamelMimeMessage *mime_message, +remove_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type, const gchar *recipient) { @@ -363,7 +363,7 @@ camel_mime_message_remove_recipient (CamelMimeMessage *mime_message, static const GList * -_get_recipients (CamelMimeMessage *mime_message, +get_recipients (CamelMimeMessage *mime_message, const gchar *recipient_type) { return camel_recipient_table_get (mime_message->recipients, recipient_type); @@ -386,7 +386,7 @@ camel_mime_message_get_recipients (CamelMimeMessage *mime_message, static void -_set_flag (CamelMimeMessage *mime_message, const gchar *flag, gboolean value) +set_flag (CamelMimeMessage *mime_message, const gchar *flag, gboolean value) { gchar *old_flags; gboolean ptr_value; @@ -413,7 +413,7 @@ camel_mime_message_set_flag (CamelMimeMessage *mime_message, const gchar *flag, static gboolean -_get_flag (CamelMimeMessage *mime_message, const gchar *flag) +get_flag (CamelMimeMessage *mime_message, const gchar *flag) { return GPOINTER_TO_INT (g_hash_table_lookup (mime_message->flags, flag)); } @@ -429,7 +429,7 @@ camel_mime_message_get_flag (CamelMimeMessage *mime_message, const gchar *flag) static void -_add_flag_to_list (gpointer key, gpointer value, gpointer user_data) +add_flag_to_list (gpointer key, gpointer value, gpointer user_data) { GList **flag_list = (GList **)user_data; gchar *flag_name = (gchar *)key; @@ -439,12 +439,12 @@ _add_flag_to_list (gpointer key, gpointer value, gpointer user_data) } static GList * -_get_flag_list (CamelMimeMessage *mime_message) +get_flag_list (CamelMimeMessage *mime_message) { GList *flag_list = NULL; if (mime_message->flags) - g_hash_table_foreach (mime_message->flags, _add_flag_to_list, &flag_list); + g_hash_table_foreach (mime_message->flags, add_flag_to_list, &flag_list); return flag_list; } @@ -460,13 +460,13 @@ camel_mime_message_get_flag_list (CamelMimeMessage *mime_message) static void -_set_message_number (CamelMimeMessage *mime_message, guint number) +set_message_number (CamelMimeMessage *mime_message, guint number) { mime_message->message_number = number; } static guint -_get_message_number (CamelMimeMessage *mime_message) +get_message_number (CamelMimeMessage *mime_message) { return mime_message->message_number; } @@ -480,37 +480,39 @@ camel_mime_message_get_message_number (CamelMimeMessage *mime_message) } /* mime_message */ -static void +static int construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp) { char *buf; int len; int state; + int ret; d(printf("constructing mime-message\n")); d(printf("mime_message::construct_from_parser()\n")); /* let the mime-part construct the guts ... */ - ((CamelMimePartClass *)parent_class)->construct_from_parser(dw, mp); + ret = ((CamelMimePartClass *)parent_class)->construct_from_parser(dw, mp); + + if (ret == -1) + return -1; /* ... then clean up the follow-on state */ state = camel_mime_parser_step(mp, &buf, &len); if (!(state == HSCAN_MESSAGE_END || state == HSCAN_EOF)) { - g_warning("Bad parser state: Expecing MESSAGE_END or EOF, got: %d", camel_mime_parser_state(mp)); + g_error("Bad parser state: Expecing MESSAGE_END or EOF, got: %d", camel_mime_parser_state(mp)); camel_mime_parser_unstep(mp); + return -1; } d(printf("mime_message::construct_from_parser() leaving\n")); +#warning "return a real error code" + return 0; } -#ifdef WHPT -#warning : WHPT is already defined !!!!!! -#endif -#define WHPT gmime_write_header_pair_to_stream - static void -_write_one_recipient_to_stream (gchar *recipient_type, +write_one_recipient_to_stream (gchar *recipient_type, GList *recipient_list, gpointer user_data) { @@ -521,15 +523,15 @@ _write_one_recipient_to_stream (gchar *recipient_type, } static void -_write_recipients_to_stream (CamelMimeMessage *mime_message, CamelStream *stream) +write_recipients_to_stream (CamelMimeMessage *mime_message, CamelStream *stream) { camel_recipient_foreach_recipient_type (mime_message->recipients, - _write_one_recipient_to_stream, + write_one_recipient_to_stream, (gpointer)stream); } -static void -_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +static int +write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimeMessage *mm = CAMEL_MIME_MESSAGE (data_wrapper); @@ -552,10 +554,10 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) #if 1 #warning need to store receipients lists to headers /* FIXME: remove this snot ... */ - _write_recipients_to_stream (mm, stream); + write_recipients_to_stream (mm, stream); #endif - CAMEL_DATA_WRAPPER_CLASS (parent_class)->write_to_stream (data_wrapper, stream); + return CAMEL_DATA_WRAPPER_CLASS (parent_class)->write_to_stream (data_wrapper, stream); } /*******************************/ @@ -563,7 +565,7 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) /* FIXME: This is totally totally broken */ static void -_set_recipient_list_from_string (CamelMimeMessage *message, const char *recipient_type, const char *recipients_string) +set_recipient_list_from_string (CamelMimeMessage *message, const char *recipient_type, const char *recipients_string) { GList *recipients_list; @@ -599,19 +601,19 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ break; case HEADER_TO: if (header_value) - _set_recipient_list_from_string (message, "To", header_value); + set_recipient_list_from_string (message, "To", header_value); else camel_recipient_table_remove_type (message->recipients, "To"); break; case HEADER_CC: if (header_value) - _set_recipient_list_from_string (message, "Cc", header_value); + set_recipient_list_from_string (message, "Cc", header_value); else camel_recipient_table_remove_type (message->recipients, "Cc"); break; case HEADER_BCC: if (header_value) - _set_recipient_list_from_string (message, "Bcc", header_value); + set_recipient_list_from_string (message, "Bcc", header_value); else camel_recipient_table_remove_type (message->recipients, "Bcc"); break; diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c index 2f1d9fd70d..decd43207c 100644 --- a/camel/camel-mime-parser.c +++ b/camel/camel-mime-parser.c @@ -1042,6 +1042,7 @@ tail_recurse: sprintf(h->boundary, "--%s--", bound); type = HSCAN_MULTIPART; } else { +#warning actually convert the multipart to text/plain here. g_warning("Multipart with no boundary, treating as text/plain"); } } else if (!strcasecmp(ct->type, "message")) { diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index 82cff22f5a..a88892873d 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -26,14 +26,10 @@ #include "gmime-content-field.h" #include "string-utils.h" #include "gmime-utils.h" -#include "camel-simple-data-wrapper.h" - #include "camel-mime-part-utils.h" - #include "camel-mime-message.h" #include "camel-multipart.h" #include "camel-mime-body-part.h" - #include "camel-seekable-substream.h" #include "camel-stream-filter.h" #include "camel-stream-mem.h" @@ -56,7 +52,7 @@ simple_data_wrapper_construct_from_parser(CamelDataWrapper *dw, CamelMimeParser CamelStream *source; char *encoding; - d(printf("constructing simple-data-wrapper\n")); + d(printf("constructing data-wrapper\n")); /* Ok, try and be smart. If we're storing a small message (typical) convert it, and store it in memory as we parse it ... if not, throw away the conversion @@ -124,7 +120,7 @@ simple_data_wrapper_construct_from_parser(CamelDataWrapper *dw, CamelMimeParser if (buffer) { CamelStream *mem; d(printf("Small message part, kept in memory!\n")); - mem = camel_stream_mem_new_with_byte_array(buffer, CAMEL_STREAM_MEM_READ); + mem = camel_stream_mem_new_with_byte_array(buffer); camel_data_wrapper_set_output_stream (dw, mem); } else { CamelSeekableSubstream *sub; @@ -172,7 +168,7 @@ camel_mime_part_construct_content_from_parser(CamelMimePart *dw, CamelMimeParser switch (camel_mime_parser_state(mp)) { case HSCAN_HEADER: d(printf("Creating body part\n")); - content = (CamelDataWrapper *)camel_simple_data_wrapper_new(); + content = camel_data_wrapper_new(); simple_data_wrapper_construct_from_parser(content, mp); break; case HSCAN_MESSAGE: diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 9d4b98a07e..3fd3ddfb89 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -30,11 +30,11 @@ #include "gmime-content-field.h" #include "string-utils.h" #include "gmime-utils.h" -#include "camel-simple-data-wrapper.h" #include "hash-table-utils.h" #include "camel-mime-part-utils.h" #include #include "camel-mime-parser.h" +#include "camel-stream-mem.h" #define d(x) @@ -61,12 +61,12 @@ static CamelMediumClass *parent_class=NULL; #define CMD_CLASS(so) CAMEL_MEDIUM_CLASS (GTK_OBJECT(so)->klass) /* from GtkObject */ -static void my_finalize (GtkObject *object); +static void finalize (GtkObject *object); /* from CamelDataWrapper */ -static void my_write_to_stream (CamelDataWrapper *data_wrapper, +static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); -static void construct_from_stream (CamelDataWrapper *dw, CamelStream *s); +static int construct_from_stream (CamelDataWrapper *dw, CamelStream *s); /* from CamelMedia */ static void add_header (CamelMedium *medium, const char *header_name, const void *header_value); @@ -74,10 +74,10 @@ static void set_header (CamelMedium *medium, con static void remove_header (CamelMedium *medium, const char *header_name); static const void *get_header (CamelMedium *medium, const char *header_name); -static void my_set_content_object (CamelMedium *medium, CamelDataWrapper *content); +static void set_content_object (CamelMedium *medium, CamelDataWrapper *content); /* from camel mime parser */ -static void construct_from_parser (CamelMimePart *, CamelMimeParser *); +static int construct_from_parser (CamelMimePart *, CamelMimeParser *); /* forward references */ static void set_disposition (CamelMimePart *mime_part, const gchar *disposition); @@ -87,7 +87,7 @@ static void set_disposition (CamelMimePart *mime_part, const gchar *disposition) /* recognize and associate them with a unique enum */ /* identifier (see CamelHeaderType above) */ static void -my_init_header_name_table() +init_header_name_table() { header_name_table = g_hash_table_new (g_strcase_hash, g_strcase_equal); g_hash_table_insert (header_name_table, "Content-Description", (gpointer)HEADER_DESCRIPTION); @@ -107,7 +107,7 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_data_wrapper_class); parent_class = gtk_type_class (camel_medium_get_type ()); - my_init_header_name_table(); + init_header_name_table(); camel_mime_part_class->construct_from_parser = construct_from_parser; @@ -116,12 +116,12 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) camel_medium_class->set_header = set_header; camel_medium_class->get_header = get_header; camel_medium_class->remove_header = remove_header; - camel_medium_class->set_content_object = my_set_content_object; + camel_medium_class->set_content_object = set_content_object; - camel_data_wrapper_class->write_to_stream = my_write_to_stream; + camel_data_wrapper_class->write_to_stream = write_to_stream; camel_data_wrapper_class->construct_from_stream= construct_from_stream; - gtk_object_class->finalize = my_finalize; + gtk_object_class->finalize = finalize; } static void @@ -170,7 +170,7 @@ camel_mime_part_get_type (void) static void -my_finalize (GtkObject *object) +finalize (GtkObject *object) { CamelMimePart *mime_part = CAMEL_MIME_PART (object); @@ -480,7 +480,7 @@ camel_mime_part_get_content_type (CamelMimePart *mime_part) static void -my_set_content_object (CamelMedium *medium, CamelDataWrapper *content) +set_content_object (CamelMedium *medium, CamelDataWrapper *content) { CamelMimePart *mime_part = CAMEL_MIME_PART (medium); GMimeContentField *object_content_field; @@ -507,39 +507,48 @@ my_set_content_object (CamelMedium *medium, CamelDataWrapper *content) #define WHPT gmime_write_header_pair_to_stream -static void -my_write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +static int +write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimePart *mp = CAMEL_MIME_PART (data_wrapper); CamelMedium *medium = CAMEL_MEDIUM (data_wrapper); CamelDataWrapper *content; + int total = 0, count; d(printf("mime_part::write_to_stream\n")); /* FIXME: something needs to be done about this ... */ + /* FIXME: need to count these bytes too */ #warning content-languages should be stored as a header gmime_write_header_with_glist_to_stream (stream, "Content-Language", mp->content_languages,", "); if (mp->headers) { struct _header_raw *h = mp->headers; while (h) { - camel_stream_write_strings (stream, h->name, isspace(h->value[0])?":":": ", h->value, "\n", NULL); + if ( (count = camel_stream_write_strings (stream, h->name, isspace(h->value[0])?":":": ", h->value, "\n", NULL) ) == -1 ) + return -1; + total += count; h = h->next; } } - camel_stream_write_string(stream,"\n"); + if ( (count = camel_stream_write_string(stream,"\n")) == -1) + return -1; + total += count; content = camel_medium_get_content_object (medium); if (content) { - camel_data_wrapper_write_to_stream(content, stream); + if ( (count = camel_data_wrapper_write_to_stream(content, stream)) == -1 ) + return -1; + total += count; } else { g_warning("No content for medium, nothing to write"); } + return total; } /* mime_part */ -static void +static int construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp) { struct _header_raw *headers; @@ -565,28 +574,42 @@ construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp) } d(printf("mime_part::construct_from_parser() leaving\n")); +#warning "Need to work out how to detect a (fatally) bad parse in the parser" + return 0; } -void +/** + * camel_mime_part_construct_from_parser: + * @mime_part: + * @mp: + * + * + * + * Return value: + **/ +int camel_mime_part_construct_from_parser(CamelMimePart *mime_part, CamelMimeParser *mp) { - CMP_CLASS (mime_part)->construct_from_parser (mime_part, mp); + return CMP_CLASS (mime_part)->construct_from_parser (mime_part, mp); } -static void +static int construct_from_stream(CamelDataWrapper *dw, CamelStream *s) { CamelMimeParser *mp; + int ret; - printf("mime_part::construct_from_stream()\n"); + d(printf("mime_part::construct_from_stream()\n")); mp = camel_mime_parser_new(); if (camel_mime_parser_init_with_stream(mp, s) == -1) { g_warning("Cannot create parser for stream"); + ret = -1; } else { - camel_mime_part_construct_from_parser((CamelMimePart *)dw, mp); + ret = camel_mime_part_construct_from_parser((CamelMimePart *)dw, mp); } gtk_object_unref((GtkObject *)mp); + return ret; } @@ -644,22 +667,30 @@ camel_mime_part_encoding_from_string (const gchar *string) * be a text string. When @text is NULL, this routine can be used as * a way to remove old text content. * + * This can only be used to set US-ASCII text currently. + * + * And only text/plain. + * + * Perhaps it should accept a type parameter? **/ void camel_mime_part_set_text (CamelMimePart *camel_mime_part, const gchar *text) { - CamelSimpleDataWrapper *simple_data_wrapper; + CamelDataWrapper *dw; + CamelStreamMem *stream; CamelMedium *medium = CAMEL_MEDIUM (camel_mime_part); if (medium->content) gtk_object_unref (GTK_OBJECT (medium->content)); + if (text) { - simple_data_wrapper = camel_simple_data_wrapper_new (); - camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (simple_data_wrapper), "text/plain"); - camel_simple_data_wrapper_set_text ( simple_data_wrapper, text); - camel_medium_set_content_object ( CAMEL_MEDIUM (camel_mime_part), CAMEL_DATA_WRAPPER (simple_data_wrapper)); - gtk_object_unref (GTK_OBJECT (simple_data_wrapper)); - } else medium->content = NULL; + dw = camel_data_wrapper_new(); + camel_data_wrapper_set_mime_type (dw, "text/plain"); + stream = (CamelStream *)camel_stream_mem_new_with_buffer(text, strlen(text)); + camel_data_wrapper_construct_from_stream(dw, (CamelStream *)stream); + camel_medium_set_content_object ( medium, dw ); + gtk_object_unref ((GtkObject *)dw); + } else { + medium->content = NULL; + } } - - diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index eb8d2b278e..fa7f9f892e 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -57,8 +57,7 @@ enum _CamelMimePartEncodingType { typedef enum _CamelMimePartEncodingType CamelMimePartEncodingType; -/* Do not change these values directly, you - would regret it one day */ +/* Do not change these values directly, you would regret it one day */ struct _CamelMimePart { CamelMedium parent_object; @@ -78,21 +77,16 @@ struct _CamelMimePart struct _header_raw *headers; /* mime headers */ }; - - -typedef struct { +typedef struct _CamelMimePartClass { CamelMediumClass parent_class; - /* Virtual methods */ - void (*construct_from_parser) (CamelMimePart *, CamelMimeParser *); + /* Virtual methods */ + int (*construct_from_parser) (CamelMimePart *, CamelMimeParser *); } CamelMimePartClass; - - /* Standard Gtk function */ 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); @@ -123,7 +117,7 @@ const gchar * camel_mime_part_encoding_to_string (CamelMimePartEnc CamelMimePartEncodingType camel_mime_part_encoding_from_string (const gchar *string); /* construction */ -void camel_mime_part_construct_from_parser (CamelMimePart *, CamelMimeParser *); +int camel_mime_part_construct_from_parser (CamelMimePart *, CamelMimeParser *); /* utility functions */ void camel_mime_part_set_text (CamelMimePart *camel_mime_part, diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c index 1ebeed4f8f..108d138004 100644 --- a/camel/camel-multipart.c +++ b/camel/camel-multipart.c @@ -54,7 +54,7 @@ static CamelMimePart * get_parent (CamelMultipart *multipart); static void set_boundary (CamelMultipart *multipart, gchar *boundary); static const gchar * get_boundary (CamelMultipart *multipart); -static void write_to_stream (CamelDataWrapper *data_wrapper, +static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static void finalize (GtkObject *object); @@ -459,61 +459,61 @@ camel_multipart_get_boundary (CamelMultipart *multipart) return CMP_CLASS (multipart)->get_boundary (multipart); } - -struct print_part_user_data { - CamelStream *stream; - const gchar *boundary; -}; - -static void -print_part (gpointer data, gpointer user_data) -{ - CamelMimeBodyPart *body_part = CAMEL_MIME_BODY_PART (data); - struct print_part_user_data *ud = user_data; - - if (ud->boundary) - camel_stream_write_strings (ud->stream, "\n--", - ud->boundary, "\n", NULL); - else camel_stream_write_strings (ud->stream, "\n--\n", NULL); - camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (body_part), - ud->stream); -} - -static void +/* this is MIME specific, doesn't belong here really */ +static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper); - struct print_part_user_data ud; const gchar *boundary; + int total = 0, count; + GList *node; /* get the bundary text */ boundary = camel_multipart_get_boundary (multipart); /* we cannot write a multipart without a boundary string */ - g_return_if_fail (boundary); + g_return_val_if_fail (boundary, -1); /* * write the preface text (usually something like * "This is a mime message, if you see this, then * your mail client probably doesn't support ...." */ - if (multipart->preface) - camel_stream_write_strings (stream, multipart->preface, NULL); + if (multipart->preface) { + count = camel_stream_write_strings (stream, multipart->preface, NULL); + if (count == -1) + return -1; + total += count; + } /* * Now, write all the parts, separated by the boundary * delimiter */ - ud.boundary = boundary; - ud.stream = stream; - if (boundary && (boundary[0] == '\0')) + if (boundary==NULL || (boundary[0] == '\0')) g_warning ("Multipart boundary is zero length\n"); - g_list_foreach (multipart->parts, print_part, (gpointer)&ud); + + node = multipart->parts; + while (node) { + if ( (count = camel_stream_write_strings (stream, "\n--", boundary?boundary:"", "\n", NULL) ) == -1 ) + return -1; + total += count; + if ( (count = camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (node->data), stream)) == -1 ) + return -1; + total += count; + node = node->next; + } /* write the terminating boudary delimiter */ - camel_stream_write_strings (stream, "\n--", boundary, "--\n", NULL); + if ( ( count = camel_stream_write_strings (stream, "\n--", boundary, "--\n", NULL) ) == -1 ) + return -1; + total += count; + + /* and finally the postface - it is NOT fatal if this fails */ + if (multipart->postface) { + if ( ( count = camel_stream_write_strings (stream, multipart->postface, NULL) ) != -1 ) + total += count; + } - /* and finally the postface */ - if (multipart->postface) - camel_stream_write_strings (stream, multipart->postface, NULL); + return total; } diff --git a/camel/camel-seekable-stream.c b/camel/camel-seekable-stream.c index b0f6e753b1..27eba97d26 100644 --- a/camel/camel-seekable-stream.c +++ b/camel/camel-seekable-stream.c @@ -34,10 +34,12 @@ static CamelStreamClass *parent_class=NULL; /* Returns the class for a CamelSeekableStream */ #define CSS_CLASS(so) CAMEL_SEEKABLE_STREAM_CLASS (GTK_OBJECT(so)->klass) -static gint _seek (CamelSeekableStream *stream, - gint offset, - CamelStreamSeekPolicy policy); -static void _reset (CamelStream *stream); +static off_t seek (CamelSeekableStream *stream, + off_t offset, + CamelStreamSeekPolicy policy); +static off_t stream_tell (CamelSeekableStream *stream); +static void reset (CamelStream *stream); +static void set_bounds (CamelSeekableStream *stream, off_t start, off_t end); static void @@ -48,10 +50,21 @@ camel_seekable_stream_class_init (CamelSeekableStreamClass *camel_seekable_strea parent_class = gtk_type_class (camel_stream_get_type ()); /* seekable stream methods */ - camel_seekable_stream_class->seek = _seek; + camel_seekable_stream_class->seek = seek; + camel_seekable_stream_class->tell = stream_tell; + camel_seekable_stream_class->set_bounds = set_bounds; /* camel stream methods overload */ - camel_stream_class->reset = _reset; + camel_stream_class->reset = reset; +} + +static void +camel_seekable_stream_init (void *o) +{ + CamelSeekableStream *stream = (CamelSeekableStream *)o; + + stream->bound_start = 0; + stream->bound_end = CAMEL_STREAM_UNBOUND; } GtkType @@ -66,7 +79,7 @@ camel_seekable_stream_get_type (void) sizeof (CamelSeekableStream), sizeof (CamelSeekableStreamClass), (GtkClassInitFunc) camel_seekable_stream_class_init, - (GtkObjectInitFunc) NULL, + (GtkObjectInitFunc) camel_seekable_stream_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, @@ -78,20 +91,15 @@ camel_seekable_stream_get_type (void) return camel_seekable_stream_type; } - - - -static gint -_seek (CamelSeekableStream *stream, - gint offset, +static off_t +seek (CamelSeekableStream *stream, + off_t offset, CamelStreamSeekPolicy policy) { g_warning ("CamelSeekableStream::seek called on default implementation \n"); return -1; } - - /** * camel_stream_seek: * @stream: a CamelStream object. @@ -102,43 +110,74 @@ _seek (CamelSeekableStream *stream, * * Return value: new position, -1 if operation failed. **/ -gint +off_t camel_seekable_stream_seek (CamelSeekableStream *stream, - gint offset, + off_t offset, CamelStreamSeekPolicy policy) { return CSS_CLASS (stream)->seek (stream, offset, policy); } - - +static off_t +stream_tell(CamelSeekableStream *stream) +{ + return stream->position; +} /** - * camel_seekable_stream_get_current_position: get the position of a stream + * camel_seekable_stream_tell: 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) +off_t +camel_seekable_stream_tell (CamelSeekableStream *stream) { - return stream->cur_pos; + return CSS_CLASS (stream)->tell (stream); } +static void +set_bounds (CamelSeekableStream *stream, off_t start, off_t end) +{ + /* store the bounds */ + stream->bound_start = start; + stream->bound_end = end; + + /* FIXME: this is probably to be reset by seek ... */ + ((CamelStream *)stream)->eos = FALSE; + + if (start > stream->position) + camel_seekable_stream_seek(stream, start, CAMEL_STREAM_SET); +} +/** + * camel_seekable_stream_set_bounds: + * @stream: + * @start: + * @end: + * + * Set the range of valid data this stream is allowed to cover. If + * there is to be no @end value, then @end should be set to + * #CAMEL_STREAM_UNBOUND. + **/ +void +camel_seekable_stream_set_bounds(CamelSeekableStream *stream, off_t start, off_t end) +{ + CSS_CLASS (stream)->set_bounds (stream, start, end); +} /* a default implementation of reset for seekable streams */ static void -_reset (CamelStream *stream) +reset (CamelStream *stream) { CamelSeekableStream *seekable_stream; g_assert (stream); seekable_stream = CAMEL_SEEKABLE_STREAM (stream); - camel_seekable_stream_seek (seekable_stream, 0, CAMEL_STREAM_SET); + camel_seekable_stream_seek (seekable_stream, seekable_stream->bound_start, CAMEL_STREAM_SET); } diff --git a/camel/camel-seekable-stream.h b/camel/camel-seekable-stream.h index cd450c27a3..fa6f58dddc 100644 --- a/camel/camel-seekable-stream.h +++ b/camel/camel-seekable-stream.h @@ -35,6 +35,8 @@ extern "C" { #endif /* __cplusplus }*/ #include +#include +#include #include "camel-types.h" #include "camel-stream.h" @@ -46,44 +48,40 @@ extern "C" { typedef enum { - CAMEL_STREAM_SET, - CAMEL_STREAM_CUR, - CAMEL_STREAM_END - + CAMEL_STREAM_SET = SEEK_SET, + CAMEL_STREAM_CUR = SEEK_CUR, + CAMEL_STREAM_END = SEEK_END } CamelStreamSeekPolicy; +#define CAMEL_STREAM_UNBOUND (~0) struct _CamelSeekableStream { CamelStream parent_object; - - guint32 cur_pos; /* current postion in the stream */ + off_t position; /* current postion in the stream */ + off_t bound_start; /* first valid position */ + off_t bound_end; /* first invalid position */ }; - - typedef struct { CamelStreamClass parent_class; /* Virtual methods */ - gint (*seek) (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy); - - + off_t (*seek) (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy); + off_t (*tell) (CamelSeekableStream *stream); + void (*set_bounds) (CamelSeekableStream *stream, off_t start, off_t end); } CamelSeekableStreamClass; - - /* Standard Gtk function */ GtkType camel_seekable_stream_get_type (void); - /* public methods */ -gint camel_seekable_stream_seek (CamelSeekableStream *stream, - gint offset, +off_t camel_seekable_stream_seek (CamelSeekableStream *stream, + off_t offset, CamelStreamSeekPolicy policy); -guint32 camel_seekable_stream_get_current_position (CamelSeekableStream *stream); - +off_t camel_seekable_stream_tell (CamelSeekableStream *stream); +void camel_seekable_stream_set_bounds (CamelSeekableStream *, off_t, off_t); #ifdef __cplusplus } diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c index 59f53c3090..55c44514b7 100644 --- a/camel/camel-seekable-substream.c +++ b/camel/camel-seekable-substream.c @@ -1,10 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-stream-fs.c : file system based stream */ - -/* +/* camel-stream-fs.c : file system based stream * - * Author : - * Bertrand Guiheneuf + * Authors: Bertrand Guiheneuf + * Michael Zucchi * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -37,42 +35,31 @@ static gint stream_write (CamelStream *stream, const gchar *buffer, gint n); static void stream_flush (CamelStream *stream); -static gint available (CamelStream *stream); static gboolean eos (CamelStream *stream); -static gint stream_seek (CamelSeekableStream *stream, - gint offset, +static off_t stream_seek (CamelSeekableStream *stream, + off_t offset, CamelStreamSeekPolicy policy); - static void finalize (GtkObject *object); static void init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent_stream, - guint32 inf_bound, - gint64 sup_bound); - - + off_t start, off_t end); 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); + 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 = stream_read; camel_stream_class->write = stream_write; camel_stream_class->flush = stream_flush; - camel_stream_class->available = available; camel_stream_class->eos = eos; camel_seekable_stream_class->seek = stream_seek; @@ -105,7 +92,6 @@ camel_seekable_substream_get_type (void) return camel_seekable_substream_type; } - static void finalize (GtkObject *object) { @@ -118,34 +104,10 @@ finalize (GtkObject *object) GTK_OBJECT_CLASS (parent_class)->finalize (object); } - -static void -set_bounds (CamelSeekableSubstream *seekable_substream, - guint32 inf_bound, gint64 sup_bound) -{ - /* store the bounds */ - seekable_substream->inf_bound = inf_bound; - seekable_substream->sup_bound = sup_bound; - - seekable_substream->eos = FALSE; -} - - -static void -reemit_parent_signal (CamelStream *parent_stream, gpointer user_data) -{ - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (user_data); - - gtk_signal_emit_by_name (GTK_OBJECT (seekable_substream), - "data_available"); -} - - static void init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent_stream, - guint32 inf_bound, gint64 sup_bound) + off_t start, off_t end) { /* Store the parent stream. */ seekable_substream->parent_stream = parent_stream; @@ -153,17 +115,7 @@ init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream gtk_object_sink (GTK_OBJECT (parent_stream)); /* Set the bound of the substream. */ - set_bounds (seekable_substream, inf_bound, sup_bound); - - /* Connect to the parent stream "data_available" signal so - * that we can reemit the signal on the seekable substream in - * case some data would be available for us - */ - gtk_signal_connect (GTK_OBJECT (parent_stream), "data_available", - reemit_parent_signal, seekable_substream); - - gtk_signal_emit_by_name (GTK_OBJECT (seekable_substream), - "data_available"); + camel_seekable_stream_set_bounds ((CamelSeekableStream *)seekable_substream, start, end); } /** @@ -184,113 +136,83 @@ init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream **/ CamelStream * camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStream *parent_stream, - guint32 inf_bound, - gint64 sup_bound) + off_t start, off_t end) { CamelSeekableSubstream *seekable_substream; g_return_val_if_fail (CAMEL_IS_SEEKABLE_STREAM (parent_stream), NULL); /* Create the seekable substream. */ - seekable_substream = - gtk_type_new (camel_seekable_substream_get_type ()); + seekable_substream = gtk_type_new (camel_seekable_substream_get_type ()); /* Initialize it. */ init_with_seekable_stream_and_bounds (seekable_substream, parent_stream, - inf_bound, sup_bound); + start, end); return CAMEL_STREAM (seekable_substream); } - static gboolean parent_reset (CamelSeekableSubstream *seekable_substream) { - CamelSeekableStream *parent, *seekable_stream = - CAMEL_SEEKABLE_STREAM (seekable_substream); - guint32 parent_stream_current_position; - guint32 position_in_parent; + CamelSeekableStream *parent, *seekable_stream = CAMEL_SEEKABLE_STREAM (seekable_substream); parent = seekable_substream->parent_stream; - g_return_val_if_fail (parent != NULL, FALSE); - parent_stream_current_position = - camel_seekable_stream_get_current_position (parent); - - /* Compute our position in the parent stream. */ - position_in_parent = - seekable_stream->cur_pos + seekable_substream->inf_bound; + g_return_val_if_fail (parent != NULL, FALSE); - /* Go to our position in the parent stream. */ - if (parent_stream_current_position != position_in_parent) { - camel_seekable_stream_seek (parent, position_in_parent, - CAMEL_STREAM_SET); + if (camel_seekable_stream_tell(parent) != seekable_stream->position) { + return camel_seekable_stream_seek(parent, seekable_stream->position, CAMEL_STREAM_SET) + == seekable_stream->position; + } else { + return TRUE; } - - /* Check if we were able to set the position in the parent. */ - parent_stream_current_position = - camel_seekable_stream_get_current_position (parent); - - return parent_stream_current_position == position_in_parent; } static gint stream_read (CamelStream *stream, gchar *buffer, gint n) { - CamelSeekableStream *seekable_stream = - CAMEL_SEEKABLE_STREAM (stream); - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (stream); - gint v, nb_to_read, position_in_parent; + CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream); + int v; + + if (n == 0) + return 0; /* Go to our position in the parent stream. */ - if (!parent_reset (seekable_substream)) { - seekable_substream->eos = TRUE; + if (!parent_reset (seekable_substream)) { + stream->eos = TRUE; return 0; } /* Compute how much byte should be read. */ - position_in_parent = - seekable_stream->cur_pos + seekable_substream->inf_bound; - if (seekable_substream->sup_bound != -1) { - nb_to_read = MIN (seekable_substream->sup_bound - - position_in_parent, n); - } else - nb_to_read = n; - - if (!nb_to_read) { - if (n) - seekable_substream->eos = TRUE; + if (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND) + n = MIN (seekable_stream->bound_end - seekable_stream->position, n); + + if (n == 0) { + stream->eos = TRUE; return 0; } - /* 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; + v = camel_stream_read (CAMEL_STREAM (seekable_substream->parent_stream), buffer, n); - /* If the return value is negative, an error occured, - * we must do something FIXME : handle exception - */ + /* ignore <0 - its an error, let the caller deal */ if (v > 0) - seekable_stream->cur_pos += v; + seekable_stream->position += v; return v; } - static gint stream_write (CamelStream *stream, const gchar *buffer, gint n) { /* NOT VALID ON SEEKABLE SUBSTREAM */ + /* Well, its entirely valid, just not implemented */ g_warning ("CamelSeekableSubstream:: seekable substream doesn't " "have a write method\n"); return -1; } - static void stream_flush (CamelStream *stream) { @@ -299,60 +221,42 @@ stream_flush (CamelStream *stream) "have a flush method\n"); } - -static gint -available (CamelStream *stream) -{ - g_warning ("CamelSeekableSubstream::available not implemented\n"); - return -1; -} - - static gboolean eos (CamelStream *stream) { - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (stream); - CamelSeekableStream *seekable_stream = - CAMEL_SEEKABLE_STREAM (stream); + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream); + CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); guint32 substream_len; gboolean eos; g_assert (stream); - if (seekable_substream->eos) + if (stream->eos) { eos = TRUE; - else { + } else { parent_reset (seekable_substream); eos = camel_stream_eos (CAMEL_STREAM (seekable_substream->parent_stream)); - if ((!eos) && (seekable_substream->sup_bound != -1)) { - substream_len = seekable_substream->sup_bound - seekable_substream->inf_bound; - eos = ( seekable_stream->cur_pos >= substream_len); + if ((!eos) && (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND)) { + substream_len = seekable_stream->bound_start - seekable_stream->bound_end; + eos = ( seekable_stream->position >= substream_len); } } return eos; } - -static gint -stream_seek (CamelSeekableStream *stream, gint offset, +/* seeks within a seekable substream follow the bound limits ... dont start at 0 */ +static off_t +stream_seek (CamelSeekableStream *seekable_stream, off_t offset, CamelStreamSeekPolicy policy) { - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (stream); - CamelSeekableStream *seekable_stream = - CAMEL_SEEKABLE_STREAM (stream); - gint64 real_offset = 0; - guint32 substream_len; - guint32 parent_pos; - gboolean seek_done = FALSE; - - substream_len = seekable_substream->sup_bound - - seekable_substream->inf_bound; + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (seekable_stream); + CamelStream *stream = (CamelStream *)seekable_stream; + off_t real_offset = 0; + off_t parent_pos; - seekable_substream->eos = FALSE; + stream->eos = FALSE; switch (policy) { case CAMEL_STREAM_SET: @@ -360,19 +264,19 @@ stream_seek (CamelSeekableStream *stream, gint offset, break; case CAMEL_STREAM_CUR: - real_offset = seekable_stream->cur_pos + offset; + real_offset = seekable_stream->position + offset; break; case CAMEL_STREAM_END: - if (seekable_substream->sup_bound != -1) - real_offset = substream_len - offset; + if (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND) + real_offset = seekable_stream->bound_end + 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; + if (parent_pos == -1) + return -1; + real_offset = parent_pos; } break; @@ -380,15 +284,12 @@ stream_seek (CamelSeekableStream *stream, gint offset, return -1; } - 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; -} + if (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND) + real_offset = MIN (real_offset, seekable_stream->bound_end); + if (real_offsetbound_start) + real_offset = seekable_stream->bound_start; + seekable_stream->position = real_offset; + return real_offset; +} diff --git a/camel/camel-seekable-substream.h b/camel/camel-seekable-substream.h index 4710f5fd5a..75a7a41cac 100644 --- a/camel/camel-seekable-substream.h +++ b/camel/camel-seekable-substream.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-seekable-substream.h : stream */ - -/* +/* camel-seekable-substream.h : stream * * Author : * Bertrand Guiheneuf @@ -38,52 +36,37 @@ extern "C" { #include "camel-types.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)) - - - struct _CamelSeekableSubstream { CamelSeekableStream parent_object; /* --**-- Private fields --**-- */ CamelSeekableStream *parent_stream; - guint32 inf_bound; /* first valid position */ - gint64 sup_bound; /* first invalid position */ - gboolean eos; }; - - typedef struct { CamelSeekableStreamClass parent_class; /* Virtual methods */ void (*init_with_seekable_stream_and_bounds) (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent_stream, - guint32 inf_bound, - gint64 sup_bound); - + off_t start, off_t end); } CamelSeekableSubstreamClass; - - /* Standard Gtk function */ GtkType camel_seekable_substream_get_type (void); - /* public methods */ /* obtain a new seekable substream */ CamelStream * camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStream *parent_stream, - guint32 inf_bound, - gint64 sup_bound); + off_t start, off_t end); #ifdef __cplusplus } diff --git a/camel/camel-simple-data-wrapper-stream.c b/camel/camel-simple-data-wrapper-stream.c deleted file mode 100644 index 14e5383f5b..0000000000 --- a/camel/camel-simple-data-wrapper-stream.c +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* camel-simple-data-wrapper-stream.c - * - * 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. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "camel-simple-data-wrapper-stream.h" -#include "camel-simple-data-wrapper.h" - - -static CamelStreamClass *parent_class = NULL; - - -/* CamelStream methods. */ - -static gint -read (CamelStream *stream, - gchar *buffer, - gint n) -{ - CamelSimpleDataWrapperStream *wrapper_stream; - CamelSimpleDataWrapper *wrapper; - GByteArray *array; - gint len; - - wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream); - wrapper = wrapper_stream->wrapper; - g_return_val_if_fail (wrapper != NULL, -1); - array = wrapper->byte_array; - - len = MIN (n, array->len - wrapper_stream->current_position); - if (len > 0) { - memcpy (buffer, wrapper_stream->current_position + array->data, len); - wrapper_stream->current_position += len; - return len; - } else { - return 0; - } -} - -static gint -write (CamelStream *stream, - const gchar *buffer, - gint n) -{ - CamelSimpleDataWrapperStream *wrapper_stream; - CamelSimpleDataWrapper *wrapper; - GByteArray *array; - gint len; - const gchar *buffer_next; - gint left; - - wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream); - wrapper = wrapper_stream->wrapper; - g_return_val_if_fail (wrapper != NULL, -1); - array = wrapper->byte_array; - - len = MIN (n, array->len - wrapper_stream->current_position); - if (len > 0) { - memcpy (array->data, buffer, len); - buffer_next = buffer + len; - left = n - len; - } else { - /* If we are past the end of the array, fill with zeros. */ - if (wrapper_stream->current_position > array->len) { - gint saved_length; - - saved_length = array->len; - g_byte_array_set_size - (array, wrapper_stream->current_position); - memset (array->data + saved_length, - 0, - (wrapper_stream->current_position - - saved_length)); - } - - buffer_next = buffer; - left = n; - } - - if (n > 0) - g_byte_array_append (array, buffer_next, left); - - wrapper_stream->current_position += n; - return n; -} - -static void -flush (CamelStream *stream) -{ - /* No op, as we don't do any buffering. */ -} - -static gint -available (CamelStream *stream) -{ - CamelSimpleDataWrapperStream *wrapper_stream; - CamelSimpleDataWrapper *wrapper; - GByteArray *array; - gint available; - - wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream); - wrapper = wrapper_stream->wrapper; - g_return_val_if_fail (wrapper != NULL, -1); - array = wrapper->byte_array; - - available = array->len - wrapper_stream->current_position; - return MAX (available, 0); -} - -static gboolean -eos (CamelStream *stream) -{ - if (available (stream) > 0) - return TRUE; - else - return FALSE; -} - -static void -close (CamelStream *stream) -{ - /* Nothing to do, we have no associated file descriptor. */ -} - -static gint -seek (CamelSeekableStream *stream, - gint offset, - CamelStreamSeekPolicy policy) -{ - CamelSimpleDataWrapperStream *wrapper_stream; - gint new_position; - - wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream); - - switch (policy) { - case CAMEL_STREAM_SET: - new_position = offset; - break; - case CAMEL_STREAM_CUR: - new_position = wrapper_stream->current_position + offset; - break; - case CAMEL_STREAM_END: - new_position = wrapper_stream->wrapper->byte_array->len - offset; - break; - default: - g_warning ("Unknown CamelStreamSeekPolicy %d.", policy); - return -1; - } - - if (new_position<0) - new_position = 0; - else if (new_position>=wrapper_stream->wrapper->byte_array->len) - new_position = wrapper_stream->wrapper->byte_array->len-1; - - wrapper_stream->current_position = new_position; - return new_position; -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - CamelSimpleDataWrapperStream *stream; - - stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (object); - - gtk_object_unref (GTK_OBJECT (stream->wrapper)); - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static void -class_init (CamelSimpleDataWrapperStreamClass *klass) -{ - GtkObjectClass *object_class; - CamelStreamClass *stream_class; - CamelSeekableStreamClass *seek_class; - - object_class = (GtkObjectClass*) klass; - stream_class = (CamelStreamClass *)klass; - seek_class = (CamelSeekableStreamClass *)klass; - - stream_class->read = read; - stream_class->write = write; - stream_class->flush = flush; - stream_class->available = available; - stream_class->eos = eos; - stream_class->close = close; - - seek_class->seek = seek; - - object_class->destroy = destroy; - - parent_class = gtk_type_class (camel_stream_get_type ()); -} - -static void -init (CamelSimpleDataWrapperStream *simple_data_wrapper_stream) -{ - simple_data_wrapper_stream->current_position = 0; -} - - -GtkType -camel_simple_data_wrapper_stream_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "CamelSimpleDataWrapperStream", - sizeof (CamelSimpleDataWrapperStream), - sizeof (CamelSimpleDataWrapperStreamClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (camel_seekable_stream_get_type (), &info); - } - - return type; -} - -void -camel_simple_data_wrapper_stream_construct (CamelSimpleDataWrapperStream *stream, - CamelSimpleDataWrapper *wrapper) -{ - g_return_if_fail (stream != NULL); - g_return_if_fail (CAMEL_IS_SIMPLE_DATA_WRAPPER_STREAM (stream)); - g_return_if_fail (wrapper != NULL); - g_return_if_fail (CAMEL_IS_SIMPLE_DATA_WRAPPER (wrapper)); - - gtk_object_ref (GTK_OBJECT (wrapper)); - stream->wrapper = wrapper; -} - -CamelStream * -camel_simple_data_wrapper_stream_new (CamelSimpleDataWrapper *wrapper) -{ - CamelStream *stream; - - g_return_val_if_fail (wrapper != NULL, NULL); - g_return_val_if_fail (CAMEL_IS_SIMPLE_DATA_WRAPPER (wrapper), NULL); - - stream = gtk_type_new (camel_simple_data_wrapper_stream_get_type ()); - - camel_simple_data_wrapper_stream_construct - (CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream), wrapper); - - return stream; -} diff --git a/camel/camel-simple-data-wrapper-stream.h b/camel/camel-simple-data-wrapper-stream.h deleted file mode 100644 index 23ba42df3e..0000000000 --- a/camel/camel-simple-data-wrapper-stream.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* camel-simple-data-wrapper-stream.h - * - * 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. - * - * Author: Ettore Perazzoli - */ - -#ifndef __CAMEL_SIMPLE_DATA_WRAPPER_STREAM_H__ -#define __CAMEL_SIMPLE_DATA_WRAPPER_STREAM_H__ - -#include -#include "camel-types.h" -#include "camel-seekable-stream.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM \ - (camel_simple_data_wrapper_stream_get_type ()) -#define CAMEL_SIMPLE_DATA_WRAPPER_STREAM(obj) \ - (GTK_CHECK_CAST ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM, CamelSimpleDataWrapperStream)) -#define CAMEL_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM, CamelSimpleDataWrapperStreamClass)) -#define CAMEL_IS_SIMPLE_DATA_WRAPPER_STREAM(obj) \ - (GTK_CHECK_TYPE ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM)) -#define CAMEL_IS_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM)) - - -typedef struct _CamelSimpleDataWrapperStreamClass CamelSimpleDataWrapperStreamClass; - -struct _CamelSimpleDataWrapperStream { - CamelSeekableStream parent; - - CamelSimpleDataWrapper *wrapper; - gint current_position; -}; - -struct _CamelSimpleDataWrapperStreamClass { - CamelSeekableStreamClass parent_class; -}; - - -GtkType camel_simple_data_wrapper_stream_get_type (void); -CamelStream *camel_simple_data_wrapper_stream_new (CamelSimpleDataWrapper *wrapper); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __CAMEL_SIMPLE_DATA_WRAPPER_STREAM_H__ */ diff --git a/camel/camel-simple-data-wrapper.c b/camel/camel-simple-data-wrapper.c deleted file mode 100644 index cb387ee04e..0000000000 --- a/camel/camel-simple-data-wrapper.c +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-simple-data-wrapper.c : simple implementation of a data wrapper */ -/* store the data in a glib byte array */ - -/* - * - * Authors: Bertrand Guiheneuf - * - * Copyright 1999, 2000 Helix Code, Inc. (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 - -#include "camel-simple-data-wrapper.h" -#include "camel-simple-data-wrapper-stream.h" -#include -#include "camel-mime-utils.h" -#include -#include -#include -#include -#include - -#include - -#define d(x) - -static CamelDataWrapperClass *parent_class = NULL; - -/* Returns the class for a CamelDataWrapper */ -#define CSDW_CLASS(so) CAMEL_SIMPLE_DATA_WRAPPER_CLASS (GTK_OBJECT (so)->klass) - -static void write_to_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); -static void finalize (GtkObject *object); -static CamelStream * get_output_stream (CamelDataWrapper *data_wrapper); -static void construct_from_stream (CamelDataWrapper *dw, CamelStream *stream); - -static void -camel_simple_data_wrapper_class_init (CamelSimpleDataWrapperClass *camel_simple_data_wrapper_class) -{ - CamelDataWrapperClass *camel_data_wrapper_class = - CAMEL_DATA_WRAPPER_CLASS (camel_simple_data_wrapper_class); - GtkObjectClass *gtk_object_class = - GTK_OBJECT_CLASS (camel_data_wrapper_class); - - parent_class = gtk_type_class (camel_data_wrapper_get_type ()); - - - /* virtual method overload */ - camel_data_wrapper_class->write_to_stream = write_to_stream; - camel_data_wrapper_class->get_output_stream = get_output_stream; - camel_data_wrapper_class->construct_from_stream = construct_from_stream; - - gtk_object_class->finalize = finalize; -} - - -static void -camel_simple_data_wrapper_init (CamelSimpleDataWrapper *wrapper) -{ - wrapper->byte_array = NULL; - wrapper->has_byte_array_stream = FALSE; -} - - -GtkType -camel_simple_data_wrapper_get_type (void) -{ - static GtkType camel_simple_data_wrapper_type = 0; - - if (!camel_simple_data_wrapper_type) { - GtkTypeInfo camel_simple_data_wrapper_info = - { - "CamelSimpleDataWrapper", - sizeof (CamelSimpleDataWrapper), - sizeof (CamelSimpleDataWrapperClass), - (GtkClassInitFunc) camel_simple_data_wrapper_class_init, - (GtkObjectInitFunc) camel_simple_data_wrapper_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_simple_data_wrapper_type = - gtk_type_unique (camel_data_wrapper_get_type (), - &camel_simple_data_wrapper_info); - } - - return camel_simple_data_wrapper_type; -} - - -static void -finalize (GtkObject *object) -{ - CamelSimpleDataWrapper *simple_data_wrapper = - CAMEL_SIMPLE_DATA_WRAPPER (object); - - if (simple_data_wrapper->byte_array) - g_byte_array_free (simple_data_wrapper->byte_array, TRUE); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - - -/** - * camel_simple_data_wrapper_new: - * - * Return value: a new CamelSimpleDataWrapper object - **/ -CamelSimpleDataWrapper * -camel_simple_data_wrapper_new (void) -{ - return (CamelSimpleDataWrapper *) - gtk_type_new (CAMEL_SIMPLE_DATA_WRAPPER_TYPE); -} - - -static void -write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) -{ - CamelSimpleDataWrapper *simple_data_wrapper = - CAMEL_SIMPLE_DATA_WRAPPER (data_wrapper); - GByteArray *array; - - array = simple_data_wrapper->byte_array; - if ( array && array->len) - camel_stream_write (stream, (gchar *)array->data, array->len); - else - parent_class->write_to_stream (data_wrapper, stream); -} - -/** - * camel_simple_data_wrapper_set_text: set some text as data wrapper content - * @simple_data_wrapper: SimpleDataWrapper object - * @text: the text to use - * - * Utility routine used to set up the content of a SimpleDataWrapper object - * to be a character string. - **/ -void -camel_simple_data_wrapper_set_text (CamelSimpleDataWrapper *simple_data_wrapper, const gchar *text) -{ - GByteArray *array; - - array = simple_data_wrapper->byte_array; - if (array) - g_byte_array_free (array, FALSE); - - array = g_byte_array_new (); - simple_data_wrapper->byte_array = array; - - g_byte_array_append (array, text, strlen (text)); -} - - -static CamelStream * -get_output_stream (CamelDataWrapper *data_wrapper) -{ - CamelSimpleDataWrapper *simple_data_wrapper; - CamelStream *output_stream = NULL; - - simple_data_wrapper = CAMEL_SIMPLE_DATA_WRAPPER (data_wrapper); - - if (simple_data_wrapper->byte_array && - !(simple_data_wrapper->has_byte_array_stream)) { - output_stream = camel_simple_data_wrapper_stream_new (simple_data_wrapper); - camel_data_wrapper_set_output_stream (data_wrapper, output_stream); - } - - return parent_class->get_output_stream (data_wrapper); -} - -static void -construct_from_stream(CamelDataWrapper *dw, CamelStream *stream) -{ - camel_data_wrapper_set_output_stream (dw, stream); -} - diff --git a/camel/camel-simple-data-wrapper.h b/camel/camel-simple-data-wrapper.h deleted file mode 100644 index 7ef69c5869..0000000000 --- a/camel/camel-simple-data-wrapper.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-simple-data-wrapper.c : simple implementation of a data wrapper */ -/* store the data in a glib byte array */ - -/* - * - * Author : - * Bertrand Guiheneuf - * - * Copyright 1999, 2000 Helix Code, Inc. (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_SIMPLE_DATA_WRAPPER_H -#define CAMEL_SIMPLE_DATA_WRAPPER_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include -#include "camel-types.h" -#include "camel-data-wrapper.h" - -#define CAMEL_SIMPLE_DATA_WRAPPER_TYPE (camel_simple_data_wrapper_get_type ()) -#define CAMEL_SIMPLE_DATA_WRAPPER(obj) (GTK_CHECK_CAST((obj), CAMEL_SIMPLE_DATA_WRAPPER_TYPE, CamelSimpleDataWrapper)) -#define CAMEL_SIMPLE_DATA_WRAPPER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SIMPLE_DATA_WRAPPER_TYPE, CamelSimpleDataWrapperClass)) -#define CAMEL_IS_SIMPLE_DATA_WRAPPER(o) (GTK_CHECK_TYPE((o), CAMEL_SIMPLE_DATA_WRAPPER_TYPE)) - - -struct _CamelSimpleDataWrapper -{ - CamelDataWrapper parent_object; - - GByteArray *byte_array; - gboolean has_byte_array_stream; -}; - - - -typedef struct { - CamelDataWrapperClass parent_class; - -} CamelSimpleDataWrapperClass; - - - -/* Standard Gtk function */ -GtkType camel_simple_data_wrapper_get_type (void); - - -/* setup method. */ -void camel_simple_data_wrapper_stream_construct (CamelSimpleDataWrapperStream *stream, - CamelSimpleDataWrapper *wrapper); - -/* public methods */ - -CamelSimpleDataWrapper *camel_simple_data_wrapper_new (void); -void camel_simple_data_wrapper_set_text (CamelSimpleDataWrapper *simple_data_wrapper, const gchar *text); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_SIMPLE_DATA_WRAPPER_H */ diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c index 4830758c9c..64146d5b2e 100644 --- a/camel/camel-stream-buffer.c +++ b/camel/camel-stream-buffer.c @@ -1,11 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-stream-buffer.c : Buffer any other other stream */ - -/* +/* camel-stream-buffer.c : Buffer any other other stream * - * Author : - * Michael Zucchi + * Authors: Michael Zucchi * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -41,18 +38,17 @@ enum { #define BUF_SIZE 1024 -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 stream_read (CamelStream *stream, gchar *buffer, gint n); +static gint stream_write (CamelStream *stream, const gchar *buffer, gint n); +static void stream_flush (CamelStream *stream); +static gboolean stream_eos (CamelStream *stream); +static void stream_close (CamelStream *stream); -static void _finalize (GtkObject *object); -static void _destroy (GtkObject *object); +static void finalize (GtkObject *object); +static void destroy (GtkObject *object); -static void _init_vbuf(CamelStreamBuffer *sbf, CamelStream *s, CamelStreamBufferMode mode, char *buf, guint32 size); -static void _init(CamelStreamBuffer *sbuf, CamelStream *s, CamelStreamBufferMode mode); +static void init_vbuf(CamelStreamBuffer *sbf, CamelStream *s, CamelStreamBufferMode mode, char *buf, guint32 size); +static void init(CamelStreamBuffer *sbuf, CamelStream *s, CamelStreamBufferMode mode); static void camel_stream_buffer_class_init (CamelStreamBufferClass *camel_stream_buffer_class) @@ -63,19 +59,18 @@ camel_stream_buffer_class_init (CamelStreamBufferClass *camel_stream_buffer_clas parent_class = gtk_type_class (camel_stream_get_type ()); /* virtual method definition */ - camel_stream_buffer_class->init = _init; - camel_stream_buffer_class->init_vbuf = _init_vbuf; + camel_stream_buffer_class->init = init; + camel_stream_buffer_class->init_vbuf = init_vbuf; /* 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_stream_class->read = stream_read; + camel_stream_class->write = stream_write; + camel_stream_class->flush = stream_flush; + camel_stream_class->eos = stream_eos; + camel_stream_class->close = stream_close; - gtk_object_class->finalize = _finalize; - gtk_object_class->destroy = _destroy; + gtk_object_class->finalize = finalize; + gtk_object_class->destroy = destroy; } @@ -120,7 +115,7 @@ camel_stream_buffer_get_type (void) static void -_destroy (GtkObject *object) +destroy (GtkObject *object) { CamelStreamBuffer *stream_buffer = CAMEL_STREAM_BUFFER (object); @@ -132,7 +127,7 @@ _destroy (GtkObject *object) static void -_finalize (GtkObject *object) +finalize (GtkObject *object) { CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (object); @@ -146,7 +141,7 @@ _finalize (GtkObject *object) } static void -_set_vbuf(CamelStreamBuffer *sbf, char *buf, CamelStreamBufferMode mode, int size) +set_vbuf(CamelStreamBuffer *sbf, char *buf, CamelStreamBufferMode mode, int size) { if (sbf->buf && !(sbf->flags & BUF_USER)) { g_free(sbf->buf); @@ -163,18 +158,18 @@ _set_vbuf(CamelStreamBuffer *sbf, char *buf, CamelStreamBufferMode mode, int siz } static void -_init_vbuf(CamelStreamBuffer *sbf, CamelStream *s, CamelStreamBufferMode mode, char *buf, guint32 size) +init_vbuf(CamelStreamBuffer *sbf, CamelStream *s, CamelStreamBufferMode mode, char *buf, guint32 size) { - _set_vbuf(sbf, buf, mode, size); + set_vbuf(sbf, buf, mode, size); if (sbf->stream) gtk_object_unref(GTK_OBJECT(sbf->stream)); sbf->stream = s; } static void -_init(CamelStreamBuffer *sbuf, CamelStream *s, CamelStreamBufferMode mode) +init(CamelStreamBuffer *sbuf, CamelStream *s, CamelStreamBufferMode mode) { - _init_vbuf(sbuf, s, mode, NULL, BUF_SIZE); + init_vbuf(sbuf, s, mode, NULL, BUF_SIZE); } @@ -257,7 +252,7 @@ CamelStream *camel_stream_buffer_new_with_vbuf (CamelStream *stream, CamelStream * Return value: number of bytes actually read. **/ static gint -_read (CamelStream *stream, gchar *buffer, gint n) +stream_read (CamelStream *stream, gchar *buffer, gint n) { CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream); int bytes_read=1; @@ -306,7 +301,7 @@ _read (CamelStream *stream, gchar *buffer, gint n) static gint -_write (CamelStream *stream, const gchar *buffer, gint n) +stream_write (CamelStream *stream, const gchar *buffer, gint n) { CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream); const gchar *bptr = buffer; @@ -348,7 +343,7 @@ _write (CamelStream *stream, const gchar *buffer, gint n) static void -_flush (CamelStream *stream) +stream_flush (CamelStream *stream) { CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream); @@ -364,18 +359,8 @@ _flush (CamelStream *stream) camel_stream_flush(sbf->stream); } - - -static gint -_available (CamelStream *stream) -{ - /* unimplemented */ - return 0; -} - - static gboolean -_eos (CamelStream *stream) +stream_eos (CamelStream *stream) { CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream); @@ -383,11 +368,11 @@ _eos (CamelStream *stream) } static void -_close (CamelStream *stream) +stream_close (CamelStream *stream) { CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream); - _flush(stream); + stream_flush(stream); camel_stream_close(sbf->stream); } diff --git a/camel/camel-stream-buffer.h b/camel/camel-stream-buffer.h index 967c33e553..a40b7957da 100644 --- a/camel/camel-stream-buffer.h +++ b/camel/camel-stream-buffer.h @@ -90,7 +90,8 @@ GtkType camel_stream_buffer_get_type (void); CamelStream *camel_stream_buffer_new (CamelStream *s, CamelStreamBufferMode mode); CamelStream *camel_stream_buffer_new_with_vbuf (CamelStream *s, CamelStreamBufferMode mode, char *buf, guint32 size); -CamelStream *camel_stream_buffer_set_vbuf (CamelStreamBuffer *b, CamelStreamBufferMode mode, char *buf, guint32 size); +/* unimplemented + CamelStream *camel_stream_buffer_set_vbuf (CamelStreamBuffer *b, CamelStreamBufferMode mode, char *buf, guint32 size); */ /* read a line of characters */ int camel_stream_buffer_gets(CamelStreamBuffer *b, char *buf, int max); diff --git a/camel/camel-stream-data-wrapper.c b/camel/camel-stream-data-wrapper.c deleted file mode 100644 index 085f051e67..0000000000 --- a/camel/camel-stream-data-wrapper.c +++ /dev/null @@ -1,199 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* camel-stream-data-wrapper.c - * - * 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. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "camel-stream-data-wrapper.h" - - -static CamelDataWrapperClass *parent_class = NULL; - - -/* CamelDataWrapper methods. */ - -static void -write_to_stream (CamelDataWrapper *data_wrapper, - CamelStream *output_stream) -{ -#define BUFFER_SIZE 4096 - gchar buffer[BUFFER_SIZE]; - CamelStreamDataWrapper *stream_data_wrapper; - CamelStream *input_stream; - - stream_data_wrapper = CAMEL_STREAM_DATA_WRAPPER (data_wrapper); - input_stream = stream_data_wrapper->stream; - - while (TRUE) { - gchar *p; - gint read, written; - - read = camel_stream_read (input_stream, buffer, BUFFER_SIZE); - if (read == 0) - break; - - p = buffer; - while (read > 0) { - written = camel_stream_write (output_stream, p, read); - - /* FIXME no way to report an error?! */ - if (written == -1) - break; - - p += written; - read -= written; - } - } -#undef BUFFER_SIZE -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - CamelStreamDataWrapper *stream_data_wrapper; - GtkObject *stream_object; - - stream_data_wrapper = CAMEL_STREAM_DATA_WRAPPER (object); - - stream_object = GTK_OBJECT (object); - stream_data_wrapper->stream = NULL; - - gtk_object_unref (stream_object); -} - - -/* This handles destruction of the associated CamelDataWrapper outside - CamelStreamDataWrapper, for debuggin purposes (this should never happen). */ -static void -stream_destroy_cb (GtkObject *object, - gpointer data) -{ - CamelStreamDataWrapper *wrapper; - - wrapper = CAMEL_STREAM_DATA_WRAPPER (data); - - /* Hack: when we destroy the stream ourselves, we set the `stream' - member to NULL first, so that we can recognize when this is done out - of our control. */ - if (wrapper->stream != NULL) { - g_warning ("CamelSimpleDataWrapperStream: associated CamelSimpleDataWrapper was destroyed."); - wrapper->stream = NULL; - } -} - - -static void -class_init (CamelStreamDataWrapperClass *class) -{ - GtkObjectClass *object_class; - CamelDataWrapperClass *data_wrapper_class; - - object_class = GTK_OBJECT_CLASS (class); - object_class->destroy = destroy; - - data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class); - data_wrapper_class->write_to_stream = write_to_stream; - - parent_class = gtk_type_class (camel_data_wrapper_get_type ()); -} - -static void -init (CamelStreamDataWrapper *wrapper) -{ - wrapper->stream = NULL; -} - - -GtkType -camel_stream_data_wrapper_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "CamelStreamDataWrapper", - sizeof (CamelStreamDataWrapper), - sizeof (CamelStreamDataWrapperClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (camel_data_wrapper_get_type (), &info); - } - - return type; -} - -/** - * camel_stream_data_wrapper_construct: - * @wrapper: A CamelStreamDataWrapper object - * @stream: A Camel stream object - * - * Construct @wrapper associating @stream to it. Notice that, after this call, - * @stream is conceptually owned by @wrapper and will be destroyed when - * @wrapper is destroyed. - **/ -void -camel_stream_data_wrapper_construct (CamelStreamDataWrapper *wrapper, - CamelStream *stream) -{ - g_return_if_fail (wrapper != NULL); - g_return_if_fail (CAMEL_IS_STREAM_DATA_WRAPPER (wrapper)); - g_return_if_fail (stream != NULL); - g_return_if_fail (CAMEL_IS_STREAM (stream)); - - wrapper->stream = stream; - gtk_signal_connect (GTK_OBJECT (stream), "destroy", - GTK_SIGNAL_FUNC (stream_destroy_cb), wrapper); -} - -/** - * camel_stream_data_wrapper_new: - * @stream: A Camel stream object - * - * Create a new stream data wrapper object for @stream. Notice that, after - * this call, @stream is conceptually owned by the new wrapper and will be - * destroyed when the wrapper is destroyed. - * - * Return value: A pointer to the new CamelStreamDataWrapper object. - **/ -CamelDataWrapper * -camel_stream_data_wrapper_new (CamelStream *stream) -{ - CamelDataWrapper *wrapper; - - wrapper = gtk_type_new (camel_stream_data_wrapper_get_type ()); - camel_stream_data_wrapper_construct - (CAMEL_STREAM_DATA_WRAPPER (wrapper), stream); - - return wrapper; -} diff --git a/camel/camel-stream-data-wrapper.h b/camel/camel-stream-data-wrapper.h deleted file mode 100644 index 55ca93ba42..0000000000 --- a/camel/camel-stream-data-wrapper.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* camel-stream-data-wrapper.h - * - * Copyright 1999, 2000 Helix Code, Inc. (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. - * - * Author: Ettore Perazzoli - */ - -#ifndef __CAMEL_STREAM_DATA_WRAPPER_H__ -#define __CAMEL_STREAM_DATA_WRAPPER_H__ - -#include -#include "camel-types.h" -#include "camel-data-wrapper.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - - -#define CAMEL_TYPE_STREAM_DATA_WRAPPER \ - (camel_stream_data_wrapper_get_type ()) -#define CAMEL_STREAM_DATA_WRAPPER(obj) \ - (GTK_CHECK_CAST ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER, CamelStreamDataWrapper)) -#define CAMEL_STREAM_DATA_WRAPPER_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_STREAM_DATA_WRAPPER, CamelStreamDataWrapperClass)) -#define CAMEL_IS_STREAM_DATA_WRAPPER(obj) \ - (GTK_CHECK_TYPE ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER)) -#define CAMEL_IS_STREAM_DATA_WRAPPER_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER)) - - -typedef struct _CamelStreamDataWrapperClass CamelStreamDataWrapperClass; - -struct _CamelStreamDataWrapper { - CamelDataWrapper parent; - - CamelStream *stream; -}; - -struct _CamelStreamDataWrapperClass { - CamelDataWrapperClass parent_class; -}; - - -GtkType camel_stream_data_wrapper_get_type (void); -CamelDataWrapper *camel_stream_data_wrapper_new (CamelStream *stream); -void camel_stream_data_wrapper_construct (CamelStreamDataWrapper *wrapper, - CamelStream *stream); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __CAMEL_STREAM_DATA_WRAPPER_H__ */ diff --git a/camel/camel-stream-filter.c b/camel/camel-stream-filter.c index 7a8491c1f8..e8f1098a12 100644 --- a/camel/camel-stream-filter.c +++ b/camel/camel-stream-filter.c @@ -48,7 +48,6 @@ static void camel_stream_filter_init (CamelStreamFilter *obj); static gint do_read (CamelStream *stream, gchar *buffer, gint n); static gint do_write (CamelStream *stream, const gchar *buffer, gint n); static void do_flush (CamelStream *stream); -static gboolean do_available (CamelStream *stream); static gboolean do_eos (CamelStream *stream); static void do_close (CamelStream *stream); static void do_reset (CamelStream *stream); @@ -118,7 +117,6 @@ camel_stream_filter_class_init (CamelStreamFilterClass *klass) camel_stream_class->read = do_read; camel_stream_class->write = do_write; camel_stream_class->flush = do_flush; - camel_stream_class->available = do_available; camel_stream_class->eos = do_eos; camel_stream_class->close = do_close; camel_stream_class->reset = do_reset; @@ -267,17 +265,6 @@ static void do_flush (CamelStream *stream) /* NO OP */ } -static gboolean do_available (CamelStream *stream) -{ - CamelStreamFilter *filter = (CamelStreamFilter *)stream; - struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); - - if (p->filteredlen >0) - return TRUE; - - return camel_stream_available(filter->source); -} - static gboolean do_eos (CamelStream *stream) { CamelStreamFilter *filter = (CamelStreamFilter *)stream; diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index fa5766de48..ae46141e19 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -1,11 +1,9 @@ /* -*- 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 + * Authors: Bertrand Guiheneuf + * Michael Zucchi * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -35,26 +33,22 @@ static CamelSeekableStreamClass *parent_class=NULL; - /* Returns the class for a CamelStreamFS */ #define CSFS_CLASS(so) CAMEL_STREAM_FS_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 gboolean _available (CamelStream *stream); -static gboolean _eos (CamelStream *stream); -static void _close (CamelStream *stream); -static gint _seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy); +static gint stream_read (CamelStream *stream, gchar *buffer, gint n); +static gint stream_write (CamelStream *stream, const gchar *buffer, gint n); +static void stream_flush (CamelStream *stream); +static void stream_close (CamelStream *stream); +static off_t stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy); -static void _finalize (GtkObject *object); -static void _destroy (GtkObject *object); +static void finalize (GtkObject *object); -static void _init_with_fd (CamelStreamFs *stream_fs, int fd); -static void _init_with_fd_and_bounds (CamelStreamFs *stream_fs, int fd, guint32 inf_bound, gint32 sup_bound); -static void _init_with_name (CamelStreamFs *stream_fs, const gchar *name, CamelStreamFsMode mode); -static void _init_with_name_and_bounds (CamelStreamFs *stream_fs, const gchar *name, CamelStreamFsMode mode, - guint32 inf_bound, gint32 sup_bound); +static void init_with_fd (CamelStreamFs *stream_fs, int fd); +static void init_with_fd_and_bounds (CamelStreamFs *stream_fs, int fd, off_t start, off_t end); +static int init_with_name (CamelStreamFs *stream_fs, const gchar *name, int flags, int mode); +static int init_with_name_and_bounds (CamelStreamFs *stream_fs, const gchar *name, int flags, int mode, + off_t start, off_t end); static void camel_stream_fs_class_init (CamelStreamFsClass *camel_stream_fs_class) @@ -66,24 +60,20 @@ camel_stream_fs_class_init (CamelStreamFsClass *camel_stream_fs_class) parent_class = gtk_type_class (camel_seekable_stream_get_type ()); /* virtual method definition */ - camel_stream_fs_class->init_with_fd = _init_with_fd; - camel_stream_fs_class->init_with_fd_and_bounds = _init_with_fd_and_bounds; - camel_stream_fs_class->init_with_name = _init_with_name; - camel_stream_fs_class->init_with_name_and_bounds = _init_with_name_and_bounds; + camel_stream_fs_class->init_with_fd = init_with_fd; + camel_stream_fs_class->init_with_fd_and_bounds = init_with_fd_and_bounds; + camel_stream_fs_class->init_with_name = init_with_name; + camel_stream_fs_class->init_with_name_and_bounds = init_with_name_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_stream_class->read = stream_read; + camel_stream_class->write = stream_write; + camel_stream_class->flush = stream_flush; + camel_stream_class->close = stream_close; - camel_seekable_stream_class->seek = _seek; - - gtk_object_class->finalize = _finalize; - gtk_object_class->destroy = _destroy; + camel_seekable_stream_class->seek = stream_seek; + gtk_object_class->finalize = finalize; } static void @@ -92,10 +82,9 @@ camel_stream_fs_init (gpointer object, gpointer klass) CamelStreamFs *stream = CAMEL_STREAM_FS (object); stream->name = NULL; - stream->eof = FALSE; + stream->fd = -1; } - GtkType camel_stream_fs_get_type (void) { @@ -120,164 +109,124 @@ camel_stream_fs_get_type (void) return camel_stream_fs_type; } - static void -_destroy (GtkObject *object) -{ - CamelStreamFs *stream_fs = CAMEL_STREAM_FS (object); - gint close_error; - - close_error = close (stream_fs->fd); - if (close_error) { - g_warning ("CamelStreamFs::destroy Error while closing " - "file descriptor\n Full error text is : %s\n", - strerror (errno)); - } - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - - -static void -_finalize (GtkObject *object) +finalize (GtkObject *object) { CamelStreamFs *stream_fs = CAMEL_STREAM_FS (object); + if (stream_fs->fd != -1) { + if (close (stream_fs->fd) == -1) + g_warning ("CamelStreamFs::finalise: Error closing file: %s", strerror (errno)); + } g_free (stream_fs->name); GTK_OBJECT_CLASS (parent_class)->finalize (object); } - - -static void -_set_bounds (CamelStreamFs *stream_fs, guint32 inf_bound, guint32 sup_bound) -{ - - /* store the bounds */ - stream_fs->inf_bound = inf_bound; - stream_fs->sup_bound = sup_bound; - - /* go to the first position */ - lseek (stream_fs->fd, inf_bound, SEEK_SET); - - CAMEL_SEEKABLE_STREAM (stream_fs)->cur_pos = 0; -} - - - - static void -_init_with_fd (CamelStreamFs *stream_fs, int fd) +init_with_fd (CamelStreamFs *stream_fs, int fd) { + off_t offset; + stream_fs->fd = fd; - stream_fs->inf_bound = 0; - stream_fs->sup_bound = -1; - CAMEL_SEEKABLE_STREAM (stream_fs)->cur_pos = 0; + offset = lseek(fd, 0, SEEK_CUR); + if (offset == -1) + offset = 0; + ((CamelSeekableStream *)stream_fs)->position = offset; } - - - static void -_init_with_fd_and_bounds (CamelStreamFs *stream_fs, int fd, guint32 inf_bound, gint32 sup_bound) +init_with_fd_and_bounds (CamelStreamFs *stream_fs, int fd, off_t start, off_t end) { CSFS_CLASS (stream_fs)->init_with_fd (stream_fs, fd); - _set_bounds (stream_fs, inf_bound, sup_bound); - + camel_seekable_stream_set_bounds((CamelSeekableStream *)stream_fs, start, end); } - - -static void -_init_with_name (CamelStreamFs *stream_fs, const gchar *name, CamelStreamFsMode mode) +static int +init_with_name (CamelStreamFs *stream_fs, const gchar *name, int flags, int mode) { - struct stat s; - int v, fd; - int flags; + int fd; - g_assert (name); - - v = stat (name, &s); - - if (mode & CAMEL_STREAM_FS_READ){ - if (mode & CAMEL_STREAM_FS_WRITE) - flags = O_RDWR | O_CREAT | O_NONBLOCK; - else - flags = O_RDONLY | O_NONBLOCK; - } else { - if (mode & CAMEL_STREAM_FS_WRITE) - flags = O_WRONLY | O_CREAT | O_NONBLOCK; - else - return; - } - - if ( (mode & CAMEL_STREAM_FS_READ) && !(mode & CAMEL_STREAM_FS_WRITE) ) - if (v == -1) { - stream_fs->fd = -1; - return; - } + g_assert(name); + g_assert(stream_fs); - - fd = open (name, flags, 0600); + fd = open (name, flags, mode); if (fd==-1) { - g_warning ("CamelStreamFs::new_with_name can not obtain " - "fd for file \"%s\"\n", name); - return; + g_warning ("CamelStreamFs::new_with_name cannot open file: %s: %s", name, strerror(errno)); + return -1; } stream_fs->name = g_strdup (name); CSFS_CLASS (stream_fs)->init_with_fd (stream_fs, fd); - - gtk_signal_emit_by_name (GTK_OBJECT (stream_fs), "data_available"); - + return 0; } - - -static void -_init_with_name_and_bounds (CamelStreamFs *stream_fs, const gchar *name, CamelStreamFsMode mode, - guint32 inf_bound, gint32 sup_bound) +static int +init_with_name_and_bounds (CamelStreamFs *stream_fs, const gchar *name, int flags, int mode, + off_t start, off_t end) { - CSFS_CLASS (stream_fs)->init_with_name (stream_fs, name, mode); - _set_bounds (stream_fs, inf_bound, (gint32)sup_bound); + if (CSFS_CLASS (stream_fs)->init_with_name (stream_fs, name, flags, mode) == -1) + return -1; + camel_seekable_stream_set_bounds((CamelSeekableStream *)stream_fs, start, end); + return 0; } - - - +/** + * camel_stream_fs_new_with_name: + * @name: + * @mode: + * + * + * + * Return value: + **/ CamelStream * -camel_stream_fs_new_with_name (const gchar *name, CamelStreamFsMode mode) +camel_stream_fs_new_with_name (const gchar *name, int flags, int mode) { CamelStreamFs *stream_fs; stream_fs = gtk_type_new (camel_stream_fs_get_type ()); - CSFS_CLASS (stream_fs)->init_with_name (stream_fs, name, mode); - if (stream_fs->fd == -1) { - gtk_object_destroy (GTK_OBJECT (stream_fs)); + if (CSFS_CLASS (stream_fs)->init_with_name (stream_fs, name, flags, mode) == -1) { + gtk_object_unref (GTK_OBJECT (stream_fs)); return NULL; } - - return CAMEL_STREAM (stream_fs); + + return (CamelStream *)stream_fs; } - +/** + * camel_stream_fs_new_with_name_and_bounds: + * @name: + * @mode: + * @inf_bound: + * @sup_bound: + * + * + * + * Return value: + **/ CamelStream * -camel_stream_fs_new_with_name_and_bounds (const gchar *name, CamelStreamFsMode mode, - guint32 inf_bound, gint32 sup_bound) +camel_stream_fs_new_with_name_and_bounds (const gchar *name, int flags, int mode, + off_t start, off_t end) { CamelStreamFs *stream_fs; stream_fs = gtk_type_new (camel_stream_fs_get_type ()); - CSFS_CLASS (stream_fs)->init_with_name_and_bounds (stream_fs, name, mode, inf_bound, sup_bound); - - return CAMEL_STREAM (stream_fs); + if (CSFS_CLASS (stream_fs)->init_with_name_and_bounds (stream_fs, name, flags, mode, start, end) == -1) { + gtk_object_unref (GTK_OBJECT (stream_fs)); + return NULL; + } + return (CamelStream *)stream_fs; } - - - - - +/** + * camel_stream_fs_new_with_fd: + * @fd: + * + * + * + * Return value: + **/ CamelStream * camel_stream_fs_new_with_fd (int fd) { @@ -289,225 +238,140 @@ camel_stream_fs_new_with_fd (int fd) return CAMEL_STREAM (stream_fs); } - - +/** + * camel_stream_fs_new_with_fd_and_bounds: + * @fd: + * @inf_bound: + * @sup_bound: + * + * + * + * Return value: + **/ CamelStream * -camel_stream_fs_new_with_fd_and_bounds (int fd, guint32 inf_bound, gint32 sup_bound) +camel_stream_fs_new_with_fd_and_bounds (int fd, off_t start, off_t end) { CamelStreamFs *stream_fs; stream_fs = gtk_type_new (camel_stream_fs_get_type ()); - CSFS_CLASS (stream_fs)->init_with_fd_and_bounds (stream_fs, fd, inf_bound, sup_bound); + CSFS_CLASS (stream_fs)->init_with_fd_and_bounds (stream_fs, fd, start, end); return CAMEL_STREAM (stream_fs); } - - -/** - * _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) +stream_read (CamelStream *stream, gchar *buffer, gint n) { CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream); - gint v = 0; - gint nb_to_read; - + CamelSeekableStream *seekable = (CamelSeekableStream *)stream; + gint v; + g_assert (n); - - if (stream_fs->sup_bound != -1) - nb_to_read = MIN (stream_fs->sup_bound - CAMEL_SEEKABLE_STREAM (stream)->cur_pos - stream_fs->inf_bound , n); - else - nb_to_read = n; - + + if (seekable->bound_end != CAMEL_STREAM_UNBOUND) + n = MIN (seekable->bound_end - seekable->position, n); + do { - v = read ( (CAMEL_STREAM_FS (stream))->fd, buffer, nb_to_read); + v = read ( stream_fs->fd, buffer, n); } while (v == -1 && errno == EINTR); if (v>0) - CAMEL_SEEKABLE_STREAM (stream)->cur_pos += v; + seekable->position += v; if (v == 0) - stream_fs->eof = TRUE; + stream->eos = TRUE; 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) +stream_write (CamelStream *stream, const gchar *buffer, gint n) { CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream); + CamelSeekableStream *seekable = (CamelSeekableStream *)stream; int v; - gint nb_bytes_written = 0; + gint written = 0; + + g_assert (stream); + g_assert (stream_fs->fd != -1); if (n <= 0) return 0; - g_assert (stream); - g_assert (stream_fs->fd); + if (seekable->bound_end != CAMEL_STREAM_UNBOUND) + n = MIN (seekable->bound_end - seekable->position, n); - /* we do not take the end bounds into account as it does not - really make any sense in the case of a write operation */ do { v = write ( stream_fs->fd, buffer, n); - if (v>0) nb_bytes_written += v; + if (v>0) + written += v; } while (v == -1 && errno == EINTR); - if (nb_bytes_written>0) - CAMEL_SEEKABLE_STREAM (stream)->cur_pos += nb_bytes_written; - - return nb_bytes_written; + if (written>0) + seekable->position += written; + return written; } - - -/** - * _flush: flush pending changes - * @stream: the stream - * - * - **/ static void -_flush (CamelStream *stream) +stream_flush (CamelStream *stream) { fsync ((CAMEL_STREAM_FS (stream))->fd); } - - -/** - * _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 gboolean -_available (CamelStream *stream) -{ - g_warning ("Not implemented yet"); - return FALSE; -} - - -/** - * _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) -{ - CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream); - - g_assert (stream_fs); - return stream_fs->eof; -} - - -/** - * _close: close a stream - * @stream: the stream - * - * - **/ static void -_close (CamelStream *stream) +stream_close (CamelStream *stream) { - close ((CAMEL_STREAM_FS (stream))->fd); + CamelStreamFs *fs = (CamelStreamFs *)stream; + if (fs->fd != -1) { + close (fs->fd); + fs->fd = -1; + } else { + g_warning("StreamFs::close() on a closed or failed stream"); + } } - -static gint -_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy) +static off_t +stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy) { - int whence; - gint return_position; - gint real_offset; CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream); - + off_t real = 0; switch (policy) { case CAMEL_STREAM_SET: - real_offset = MAX (stream_fs->inf_bound + offset, stream_fs->inf_bound); - if (stream_fs->sup_bound > 0) - real_offset = MIN (real_offset, stream_fs->sup_bound); - whence = SEEK_SET; + real = offset; break; - case CAMEL_STREAM_CUR: - if ((stream_fs->sup_bound != -1) && ((CAMEL_SEEKABLE_STREAM (stream)->cur_pos + stream_fs->inf_bound + offset) > stream_fs->sup_bound)) { - real_offset = stream_fs->sup_bound; - whence = SEEK_SET; - } else if ((CAMEL_SEEKABLE_STREAM (stream)->cur_pos + stream_fs->inf_bound + offset) < stream_fs->inf_bound) { - real_offset = stream_fs->inf_bound; - whence = SEEK_SET; - } else - { - real_offset = offset; - whence = SEEK_CUR; - } + real = stream->position + offset; break; - case CAMEL_STREAM_END: - if (stream_fs->sup_bound != -1) { - real_offset = stream_fs->sup_bound - offset; - whence = SEEK_SET; - } else { - real_offset = offset; - whence = SEEK_END; + if (stream->bound_end != CAMEL_STREAM_UNBOUND) { + real = lseek(stream_fs->fd, offset, SEEK_END); + if (real != -1) + stream->position = real; + return real; } - - + real = stream->bound_end + offset; break; default: + errno = EINVAL; return -1; } - - - - return_position = lseek (stream_fs->fd, real_offset, whence) - stream_fs->inf_bound; - if (((CAMEL_SEEKABLE_STREAM (stream)->cur_pos) != return_position) && stream_fs->eof) - stream_fs->eof = FALSE; - - CAMEL_SEEKABLE_STREAM (stream)->cur_pos = return_position; - - - return return_position; -} - - - - - - + if (stream->bound_end != CAMEL_STREAM_UNBOUND) { + real = MIN (real, stream->bound_end); + } + real = MAX (real, stream->bound_start); + real = lseek(stream_fs->fd, real, SEEK_SET); + if (real == -1) + return -1; + if (real != stream->position && ((CamelStream *)stream)->eos) + ((CamelStream *)stream)->eos = FALSE; + stream->position = real; + + return real; +} diff --git a/camel/camel-stream-fs.h b/camel/camel-stream-fs.h index 7d39c5f382..d3e8f219c7 100644 --- a/camel/camel-stream-fs.h +++ b/camel/camel-stream-fs.h @@ -35,37 +35,27 @@ extern "C" { #endif /* __cplusplus }*/ #include -#include "camel-types.h" -#include "camel-seekable-stream.h" +#include +#include + +/* for open flags */ +#include +#include +#include #define CAMEL_STREAM_FS_TYPE (camel_stream_fs_get_type ()) #define CAMEL_STREAM_FS(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_FS_TYPE, CamelStreamFs)) #define CAMEL_STREAM_FS_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_FS_TYPE, CamelStreamFsClass)) #define CAMEL_IS_STREAM_FS(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_FS_TYPE)) -typedef enum -{ - CAMEL_STREAM_FS_READ = 1, - CAMEL_STREAM_FS_WRITE = 2 - -} CamelStreamFsMode; - - struct _CamelStreamFs { - CamelSeekableStream parent_object; gchar *name; /* name of the underlying file */ - gboolean eof; /* are we at the end of the file ? */ gint fd; /* file descriptor on the underlying file */ - guint32 inf_bound; /* first valid position */ - gint32 sup_bound; /* last valid position, -1 means, no sup bound */ - }; - - typedef struct { CamelSeekableStreamClass parent_class; @@ -73,38 +63,29 @@ typedef struct { void (*init_with_fd) (CamelStreamFs *stream_fs, int fd); void (*init_with_fd_and_bounds) (CamelStreamFs *stream_fs, - int fd, guint32 inf_bound, - gint32 sup_bound); + int fd, off_t start, off_t end); - void (*init_with_name) (CamelStreamFs *stream_fs, + int (*init_with_name) (CamelStreamFs *stream_fs, const gchar *name, - CamelStreamFsMode mode); - void (*init_with_name_and_bounds) (CamelStreamFs *stream_fs, + int flags, int mode); + int (*init_with_name_and_bounds) (CamelStreamFs *stream_fs, const gchar *name, - CamelStreamFsMode mode, - guint32 inf_bound, - gint32 sup_bound); - + int flags, int mode, + off_t start, off_t end); } CamelStreamFsClass; - - /* Standard Gtk function */ GtkType camel_stream_fs_get_type (void); /* public methods */ -CamelStream * camel_stream_fs_new_with_name (const gchar *name, - CamelStreamFsMode mode); +CamelStream * camel_stream_fs_new_with_name (const gchar *name, int flags, int mode); CamelStream * camel_stream_fs_new_with_name_and_bounds (const gchar *name, - CamelStreamFsMode mode, - guint32 inf_bound, - gint32 sup_bound); + int flags, int mode, + off_t start, off_t end); CamelStream * camel_stream_fs_new_with_fd (int fd); -CamelStream * camel_stream_fs_new_with_fd_and_bounds (int fd, - guint32 inf_bound, - gint32 sup_bound); +CamelStream * camel_stream_fs_new_with_fd_and_bounds (int fd, off_t start, off_t end); #ifdef __cplusplus } diff --git a/camel/camel-stream-mem.c b/camel/camel-stream-mem.c index 3e33f18f08..837fa17560 100644 --- a/camel/camel-stream-mem.c +++ b/camel/camel-stream-mem.c @@ -1,11 +1,9 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-stream-mem.c : memory buffer based stream */ - -/* inspired by gnome-stream-mem.c in bonobo by Miguel de Icaza */ -/* +/* camel-stream-mem.c : memory buffer based stream + * inspired by gnome-stream-mem.c in bonobo by Miguel de Icaza * - * Author : - * Bertrand Guiheneuf + * Authors: Bertrand Guiheneuf + * Michael Zucchi * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -33,19 +31,17 @@ static CamelStreamClass *parent_class=NULL; - /* Returns the class for a CamelStreamMEM */ #define CSM_CLASS(so) CAMEL_STREAM_MEM_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 gint stream_read (CamelStream *stream, gchar *buffer, gint n); +static gint stream_write (CamelStream *stream, const gchar *buffer, gint n); +static void stream_flush (CamelStream *stream); +static gboolean stream_eos (CamelStream *stream); +static void stream_close (CamelStream *stream); +static off_t stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy); -static void _finalize (GtkObject *object); +static void finalize (GtkObject *object); static void camel_stream_mem_class_init (CamelStreamMemClass *camel_stream_mem_class) @@ -59,24 +55,23 @@ camel_stream_mem_class_init (CamelStreamMemClass *camel_stream_mem_class) /* virtual method definition */ /* 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; + camel_stream_class->read = stream_read; + camel_stream_class->write = stream_write; + camel_stream_class->flush = stream_flush; + camel_stream_class->eos = stream_eos; + camel_stream_class->close = stream_close; + + camel_seekable_stream_class->seek = stream_seek; + gtk_object_class->finalize = finalize; } static void camel_stream_mem_init (gpointer object, gpointer klass) { - CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (object); - camel_stream_mem->position = 0; + CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (object); + stream_mem->owner = FALSE; + stream_mem->buffer = 0; } GtkType @@ -105,191 +100,169 @@ camel_stream_mem_get_type (void) CamelStream * -camel_stream_mem_new (CamelStreamMemMode mode) +camel_stream_mem_new (void) { - return camel_stream_mem_new_with_byte_array (g_byte_array_new (), - mode); + return camel_stream_mem_new_with_byte_array (g_byte_array_new ()); } CamelStream * -camel_stream_mem_new_with_buffer (const char *buffer, unsigned int len, - CamelStreamMemMode mode) +camel_stream_mem_new_with_buffer (const char *buffer, unsigned int len) { GByteArray *ba; ba = g_byte_array_new (); g_byte_array_append (ba, (const guint8 *)buffer, len); - return camel_stream_mem_new_with_byte_array (ba, mode); + return camel_stream_mem_new_with_byte_array (ba); } CamelStream * -camel_stream_mem_new_with_byte_array (GByteArray *byte_array, - CamelStreamMemMode mode) +camel_stream_mem_new_with_byte_array (GByteArray *byte_array) { CamelStreamMem *stream_mem; stream_mem = gtk_type_new (camel_stream_mem_get_type ()); - stream_mem->mode = mode; stream_mem->buffer = byte_array; + stream_mem->owner = TRUE; return CAMEL_STREAM (stream_mem); } +/* note: with these functions the caller is the 'owner' of the buffer */ +void camel_stream_mem_set_byte_array (CamelStreamMem *s, GByteArray *buffer) +{ + if (s->buffer && s->owner) + g_byte_array_free(s->buffer, TRUE); + s->owner = FALSE; + s->buffer = buffer; +} + +void camel_stream_mem_set_buffer (CamelStreamMem *s, const char *buffer, size_t len) +{ + GByteArray *ba; + ba = g_byte_array_new (); + g_byte_array_append (ba, (const guint8 *)buffer, len); + camel_stream_mem_set_byte_array(s, ba); +} static void -_finalize (GtkObject *object) +finalize (GtkObject *object) { CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (object); - if (stream_mem->buffer) + if (stream_mem->buffer && stream_mem->owner) g_byte_array_free (stream_mem->buffer, TRUE); GTK_OBJECT_CLASS (parent_class)->finalize (object); } - - -/** - * _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) +stream_read (CamelStream *stream, gchar *buffer, gint n) { CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (stream); - gint nb_bytes_to_read; + CamelSeekableStream *seekable = (CamelSeekableStream *)stream; g_assert (stream); - nb_bytes_to_read = MIN (n, (camel_stream_mem->buffer)->len - camel_stream_mem->position); - if (nb_bytes_to_read>0) { - memcpy (buffer, (camel_stream_mem->buffer)->data + camel_stream_mem->position, nb_bytes_to_read); - camel_stream_mem->position += nb_bytes_to_read; - } else nb_bytes_to_read = -1; - return nb_bytes_to_read; -} + if (seekable->bound_end != CAMEL_STREAM_UNBOUND) { + n = MIN(seekable->bound_end - seekable->position, n); + } + + n = MIN (n, camel_stream_mem->buffer->len - seekable->position); + if (n>0) { + memcpy (buffer, (camel_stream_mem->buffer)->data + seekable->position, n); + seekable->position += n; + } else { + n = -1; + } + return n; +} -/** - * _write: read 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) +stream_write (CamelStream *stream, const gchar *buffer, gint n) { - CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (stream); + CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream); + CamelSeekableStream *seekable = (CamelSeekableStream *)stream; g_assert (stream); - g_return_val_if_fail (camel_stream_mem->position>=0, -1); - camel_stream_mem->buffer = g_byte_array_append (camel_stream_mem->buffer, (const guint8 *)buffer, n); - camel_stream_mem->position += n; + + if (seekable->bound_end != CAMEL_STREAM_UNBOUND) { + n = MIN(seekable->bound_end - seekable->position, n); + } + +#warning "g_byte_arrays use g_malloc and so are totally unsuitable for this object" + if (seekable->position == stream_mem->buffer->len) { + stream_mem->buffer = g_byte_array_append (stream_mem->buffer, (const guint8 *)buffer, n); + } else { + g_byte_array_set_size(stream_mem->buffer, n+stream_mem->buffer->len); + memcpy(stream_mem->buffer->data + seekable->position, buffer, n); + } + seekable->position += n; return n; } - - -/** - * _flush: flush pending changes - * @stream: the stream - * - * - **/ static void -_flush (CamelStream *stream) +stream_flush (CamelStream *stream) { /* Nothing to do. */ return; } - - -/** - * _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) -{ - CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (stream); - - return camel_stream_mem->buffer->len - camel_stream_mem->position; -} - - -/** - * _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) +stream_eos (CamelStream *stream) { - return _available (stream) == 0; + return ((CamelStreamMem *)stream)->buffer->len <= ((CamelSeekableStream *)stream)->position; } - -/** - * _close: close a stream - * @stream: the stream - * - * - **/ static void -_close (CamelStream *stream) +stream_close (CamelStream *stream) { CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream); - if (stream_mem->buffer) + if (stream_mem->buffer && stream_mem->owner) g_byte_array_free (stream_mem->buffer, TRUE); stream_mem->buffer = NULL; } - - -static gint -_seek (CamelSeekableStream *stream, gint offset, CamelStreamSeekPolicy policy) +static off_t +stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy) { - gint position; - CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (stream); + off_t position; + CamelStreamMem *stream_mem = (CamelStreamMem *)stream; switch (policy) { case CAMEL_STREAM_SET: position = offset; break; case CAMEL_STREAM_CUR: - position = camel_stream_mem->position + offset; + position = stream->position + offset; break; case CAMEL_STREAM_END: - position = (camel_stream_mem->buffer)->len + offset; + position = (stream_mem->buffer)->len + offset; break; default: + errno = EINVAL; return -1; } - - position = MIN (position, (camel_stream_mem->buffer)->len); - position = MAX (position, 0); - camel_stream_mem->position = position; + if (stream->bound_end == CAMEL_STREAM_UNBOUND) { + position = MIN (position, stream->bound_end); + } + if (stream->bound_start == CAMEL_STREAM_UNBOUND) { + position = MAX (position, 0); + } else { + position = MAX (position, stream->bound_start); + } + + if (position > stream_mem->buffer->len) { + int oldlen = stream_mem->buffer->len; + g_byte_array_set_size(stream_mem->buffer, position); + memset(stream_mem->buffer->data + oldlen, 0, position - oldlen); + } + + stream->position = position; return position; } diff --git a/camel/camel-stream-mem.h b/camel/camel-stream-mem.h index 65b9748715..785fddad60 100644 --- a/camel/camel-stream-mem.h +++ b/camel/camel-stream-mem.h @@ -1,10 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-stream-mem.h :stream based on memory buffer */ - -/* +/* camel-stream-mem.h :stream based on memory buffer * - * Author : - * Bertrand Guiheneuf + * Authors: Bertrand Guiheneuf + * Michael Zucchi * * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) * @@ -35,6 +33,7 @@ extern "C" { #endif /* __cplusplus }*/ #include +#include #include "camel-types.h" #include "camel-seekable-stream.h" @@ -43,47 +42,31 @@ extern "C" { #define CAMEL_STREAM_MEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_MEM_TYPE, CamelStreamMemClass)) #define CAMEL_IS_STREAM_MEM(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_MEM_TYPE)) -typedef enum -{ - CAMEL_STREAM_MEM_READ = 1, - CAMEL_STREAM_MEM_WRITE = 2, - CAMEL_STREAM_MEM_RW = 3 -} CamelStreamMemMode; - - struct _CamelStreamMem { CamelSeekableStream parent_object; + gboolean owner; /* do we own the buffer? */ GByteArray *buffer; - gint position; - CamelStreamMemMode mode; - }; - - typedef struct { CamelSeekableStreamClass parent_class; /* Virtual methods */ - } CamelStreamMemClass; - - /* Standard Gtk function */ GtkType camel_stream_mem_get_type (void); - /* public methods */ -CamelStream *camel_stream_mem_new (CamelStreamMemMode mode); -CamelStream *camel_stream_mem_new_with_byte_array (GByteArray *buffer, - CamelStreamMemMode mode); -CamelStream *camel_stream_mem_new_with_buffer (const char *buffer, - unsigned int len, - CamelStreamMemMode mode); +CamelStream *camel_stream_mem_new (void); +CamelStream *camel_stream_mem_new_with_byte_array (GByteArray *buffer); +CamelStream *camel_stream_mem_new_with_buffer (const char *buffer, size_t len); +/* these are really only here for implementing classes */ +void camel_stream_mem_set_byte_array (CamelStreamMem *, GByteArray *buffer); +void camel_stream_mem_set_buffer (CamelStreamMem *, const char *buffer, size_t len); #ifdef __cplusplus } diff --git a/camel/camel-stream.c b/camel/camel-stream.c index aaa782620e..bb8c6362ec 100644 --- a/camel/camel-stream.c +++ b/camel/camel-stream.c @@ -53,6 +53,12 @@ default_camel_close (CamelStream *stream) /* nothing */ } +static gboolean +eos (CamelStream *stream) +{ + return stream->eos; +} + static void camel_stream_class_init (CamelStreamClass *camel_stream_class) @@ -65,8 +71,7 @@ camel_stream_class_init (CamelStreamClass *camel_stream_class) camel_stream_class->read = NULL; camel_stream_class->write = NULL; camel_stream_class->flush = default_camel_flush; - camel_stream_class->available = NULL; - camel_stream_class->eos = NULL; + camel_stream_class->eos = eos; camel_stream_class->close = default_camel_close; camel_stream_class->close = NULL; @@ -155,18 +160,6 @@ camel_stream_flush (CamelStream *stream) CS_CLASS (stream)->flush (stream); } -/** - * camel_stream_available: - * @stream: a CamelStream object - * - * Return value: %TRUE if some data is available for reading, %FALSE otherwise - **/ -gboolean -camel_stream_available (CamelStream *stream) -{ - return CS_CLASS (stream)->available (stream); -} - /** * camel_stream_eos: * @stream: a CamelStream object @@ -195,9 +188,6 @@ camel_stream_close (CamelStream *stream) CS_CLASS (stream)->close (stream); } - - - /** * camel_stream_reset: reset a stream * @stream: the stream object @@ -214,9 +204,6 @@ camel_stream_reset (CamelStream *stream) CS_CLASS (stream)->reset (stream); } - - - /***************** Utility functions ********************/ /** @@ -226,21 +213,46 @@ camel_stream_reset (CamelStream *stream) * * This is a utility function that writes the list of * strings into the @stream object. + * + * Returns number of successfully written bytes. */ -void +int camel_stream_write_strings (CamelStream *stream, ... ) { va_list args; const char *string; - + int total = 0; + va_start(args, stream); string = va_arg (args, const char *); while (string) { - camel_stream_write_string (stream, string); + int ret = camel_stream_write_string (stream, string); + if (ret == -1) + return -1; + total += ret; string = va_arg (args, char *); } va_end (args); + return total; +} + +int camel_stream_printf (CamelStream *stream, const char *fmt, ... ) +{ + va_list args; + char *string; + int ret = 0; + + va_start(args, fmt); + /* sigh, this allocates ... */ + string = g_strdup_vprintf(fmt, args); + if (string) { + ret = camel_stream_write_string(stream, string); + g_free(string); + } + va_end(args); + + return ret; } /** @@ -251,13 +263,15 @@ camel_stream_write_strings (CamelStream *stream, ... ) * Write all of a stream (until eos) into another stream, in a blocking * fashion. * - * FIXME: This really needs to return an error code. + * Return Value: Returns -1 on error, or the number of bytes succesfully + * copied across streams. **/ -void +int camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream) { gchar tmp_buf[4096]; + int total = 0; gint nb_read; gint nb_written; @@ -271,16 +285,19 @@ camel_stream_write_to_stream (CamelStream *stream, while (!camel_stream_eos (CAMEL_STREAM (stream))) { nb_read = camel_stream_read (CAMEL_STREAM (stream), tmp_buf, 4096); - if (nb_read>0) { + if (nb_read < 0) + return -1; + else if (nb_read>0) { nb_written = 0; while (nb_written < nb_read) { int len = camel_stream_write (output_stream, tmp_buf + nb_written, nb_read - nb_written); - /* FIXME: what about length 0? */ if (len<0) - return; + return -1; nb_written += len; } + total += nb_written; } - } + } + return total; } diff --git a/camel/camel-stream.h b/camel/camel-stream.h index bd1123c1c8..9a4e96122b 100644 --- a/camel/camel-stream.h +++ b/camel/camel-stream.h @@ -42,15 +42,13 @@ extern "C" { #define CAMEL_STREAM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_TYPE, CamelStreamClass)) #define CAMEL_IS_STREAM(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_TYPE)) - struct _CamelStream { GtkObject parent_object; + gboolean eos; /* end of stream indicator, for use by implementing classes */ }; - - typedef struct { GtkObjectClass parent_class; @@ -61,42 +59,29 @@ typedef struct { gint (*read) (CamelStream *stream, gchar *buffer, gint n); gint (*write) (CamelStream *stream, const gchar *buffer, gint n); void (*flush) (CamelStream *stream); - gboolean (*available) (CamelStream *stream); gboolean (*eos) (CamelStream *stream); void (*close) (CamelStream *stream); void (*reset) (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); -gboolean camel_stream_available (CamelStream *stream); gboolean camel_stream_eos (CamelStream *stream); void camel_stream_close (CamelStream *stream); void camel_stream_reset (CamelStream *stream); - - - /* utility macros and funcs */ -#define camel_stream_write_string(stream, string) camel_stream_write ((stream), (string), strlen (string)) +#define camel_stream_write_string(stream, string) (camel_stream_write ((stream), (string), strlen (string))) +int camel_stream_write_strings (CamelStream *stream, ... ); +int camel_stream_printf (CamelStream *stream, const char *fmt, ... ) G_GNUC_PRINTF (2, 3); -void camel_stream_write_strings (CamelStream *stream, ... ); -/* write a whole stream to another stream, until eof */ -/* FIXME: this should definetly have an error return code */ -void camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream); +/* write a whole stream to another stream, until eof or error on either stream */ +int camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream); #ifdef __cplusplus } diff --git a/camel/camel.h b/camel/camel.h index d46f2e3b9a..69fd7eb527 100644 --- a/camel/camel.h +++ b/camel/camel.h @@ -36,7 +36,6 @@ extern "C" { #include #include #include -#include #include #include #include @@ -56,7 +55,6 @@ extern "C" { #include #include #include -#include #include #include #include diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index be02a472c6..91ac79c22e 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -676,6 +676,7 @@ _get_message_count (CamelFolder *folder, CamelException *ex) */ /* FIXME: this may need some tweaking for performance? */ +/* FIXME: MUST check all sytem call return codes MUST MUST */ static void _append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex) { @@ -745,7 +746,7 @@ _append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException } /* its not an mbox folder, so lets do it the slow way ... */ - output_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, CAMEL_STREAM_FS_WRITE); + output_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, O_CREAT|O_RDWR, 0600); if (output_stream == NULL) { camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */ @@ -851,14 +852,20 @@ _get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) /* FIXME: more checks below */ /* create a stream bound to the message position/size */ - message_stream = camel_stream_fs_new_with_name_and_bounds (mbox_folder->folder_file_path, - CAMEL_STREAM_FS_READ, + message_stream = camel_stream_fs_new_with_name_and_bounds (mbox_folder->folder_file_path, O_RDONLY, 0, ((CamelMboxMessageContentInfo *)info->info.content)->pos, ((CamelMboxMessageContentInfo *)info->info.content)->endpos); gtk_object_ref((GtkObject *)message_stream); gtk_object_sink((GtkObject *)message_stream); message = camel_mime_message_new(); - camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream); + if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, message_stream) == -1) { + gtk_object_unref((GtkObject *)message); + gtk_object_unref((GtkObject *)message_stream); + camel_exception_setv (ex, + CAMEL_EXCEPTION_FOLDER_INVALID_UID, /* FIXME: code */ + "Could not create message for uid %s: %s", uid, strerror(errno)); + return NULL; + } gtk_object_unref((GtkObject *)message_stream); /* init other fields? */ diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c index f1d4a41b7d..5608afc3df 100644 --- a/camel/providers/mbox/camel-mbox-summary.c +++ b/camel/providers/mbox/camel-mbox-summary.c @@ -768,7 +768,7 @@ static int index_folder(CamelMboxSummary *s, int startoffset) int docopy = FALSE; /* check for X-Evolution header ... if its there, nothing to do (skip content) */ - xev = camel_mime_parser_header(mp, "x-evolution", &xevoffset); + xev = camel_mime_parser_header(mp, "x-evolution", (int *)&xevoffset); if (xev) { d(printf("An x-evolution header exists at: %d = %s\n", xevoffset + write_offset, xev)); xevoffset = xevoffset + write_offset; diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index 7653dbdb6b..f47851a6a4 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -205,8 +205,7 @@ get_message_by_number (CamelFolder *folder, gint number, CamelException *ex) return NULL; } - msgstream = camel_stream_mem_new_with_buffer (body, strlen (body), - CAMEL_STREAM_MEM_READ); + msgstream = camel_stream_mem_new_with_buffer (body, strlen (body)); msg = camel_mime_message_new (); camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), msgstream); -- cgit v1.2.3