Use CamelException to signal failure. (camel_stream_write_strings):
* camel-stream.c (camel_stream_read, camel_stream_write, camel_stream_flush, camel_stream_reset, camel_stream_printf, camel_stream_write_to_stream): Use CamelException to signal failure. (camel_stream_write_strings): Remove. camel_stream_printf is more useful in most of the places that used this. (camel_stream_write_string): Change from macro to function to prevent problems with double-evaluation. * camel-seekable-stream.c (camel_seekable_stream_seek, camel_seekable_stream_set_bounds): Use CamelException. (reset): Update. * camel-seekable-substream.c, camel-stream-buffer.c, camel-stream-filter.c, camel-stream-fs.c, camel-stream-mem.c: Update. * camel-stream-fs.c: Remove the virtual init functions and move the code into the creator functions. Add CamelExceptions to creation functions that could fail. * camel-data-wrapper.c (camel_data_wrapper_write_to_stream): Use CamelException. * camel-mime-message.c, camel-mime-part.c, camel-multipart.c (write_to_stream): Update. * camel-mime-parser.c: add an exception to the mime parser private data and pass that to stream functions as needed. * gmime-content-field.c, md5-utils.c: Update (badly) for stream changes. * camel-exception.h (camel_exception_is_set): convenience macro. * providers/Makefile.am: disable SMTP for now * providers/mbox/camel-mbox-folder.c (mbox_append_message): Pass CamelException to the functions that now need it. Check the exception after calling camel_stream_flush, and fail if it fails. (mbox_get_message_by_uid): More updates. * providers/pop/camel-pop3-folder.c, providers/pop/camel-pop3-store.c, providers/sendmail/camel-sendmail/transport.c: Update. svn path=/trunk/; revision=2924
This commit is contained in:
@ -1,3 +1,51 @@
|
||||
2000-05-08 Dan Winship <danw@helixcode.com>
|
||||
|
||||
* camel-stream.c (camel_stream_read, camel_stream_write,
|
||||
camel_stream_flush, camel_stream_reset, camel_stream_printf,
|
||||
camel_stream_write_to_stream): Use CamelException to signal
|
||||
failure.
|
||||
(camel_stream_write_strings): Remove. camel_stream_printf is more
|
||||
useful in most of the places that used this.
|
||||
(camel_stream_write_string): Change from macro to function to
|
||||
prevent problems with double-evaluation.
|
||||
|
||||
* camel-seekable-stream.c (camel_seekable_stream_seek,
|
||||
camel_seekable_stream_set_bounds): Use CamelException.
|
||||
(reset): Update.
|
||||
|
||||
* camel-seekable-substream.c, camel-stream-buffer.c,
|
||||
camel-stream-filter.c, camel-stream-fs.c, camel-stream-mem.c:
|
||||
Update.
|
||||
|
||||
* camel-stream-fs.c: Remove the virtual init functions and move
|
||||
the code into the creator functions. Add CamelExceptions to
|
||||
creation functions that could fail.
|
||||
|
||||
* camel-data-wrapper.c (camel_data_wrapper_write_to_stream): Use
|
||||
CamelException.
|
||||
* camel-mime-message.c, camel-mime-part.c, camel-multipart.c
|
||||
(write_to_stream): Update.
|
||||
|
||||
* camel-mime-parser.c: add an exception to the mime parser private
|
||||
data and pass that to stream functions as needed.
|
||||
|
||||
* gmime-content-field.c, md5-utils.c: Update (badly) for stream
|
||||
changes.
|
||||
|
||||
* camel-exception.h (camel_exception_is_set): convenience macro.
|
||||
|
||||
* providers/Makefile.am: disable SMTP for now
|
||||
|
||||
* providers/mbox/camel-mbox-folder.c (mbox_append_message): Pass
|
||||
CamelException to the functions that now need it. Check the
|
||||
exception after calling camel_stream_flush, and fail if it fails.
|
||||
(mbox_get_message_by_uid): More updates.
|
||||
|
||||
* providers/pop/camel-pop3-folder.c,
|
||||
providers/pop/camel-pop3-store.c,
|
||||
providers/sendmail/camel-sendmail/transport.c: Update.
|
||||
|
||||
|
||||
2000-05-08 NotZed <NotZed@HelixCode.com>
|
||||
|
||||
* camel-mime-message.c (process_header): Format From and Reply-To
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
*/
|
||||
#include <config.h>
|
||||
#include "camel-data-wrapper.h"
|
||||
#include "camel-exception.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@ -41,7 +42,7 @@ static CamelStream *get_output_stream (CamelDataWrapper *data_wrapper);
|
||||
|
||||
static int construct_from_stream(CamelDataWrapper *, CamelStream *);
|
||||
static int write_to_stream (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream);
|
||||
CamelStream *stream, CamelException *ex);
|
||||
static void set_mime_type (CamelDataWrapper *data_wrapper,
|
||||
const gchar *mime_type);
|
||||
static gchar *get_mime_type (CamelDataWrapper *data_wrapper);
|
||||
@ -204,44 +205,44 @@ camel_data_wrapper_get_output_stream (CamelDataWrapper *data_wrapper)
|
||||
|
||||
|
||||
static int
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStream *output_stream;
|
||||
|
||||
d(printf("data_wrapper::write_to_stream\n"));
|
||||
|
||||
output_stream = camel_data_wrapper_get_output_stream (data_wrapper);
|
||||
if (!output_stream) {
|
||||
g_warning("write to stream with no stream");
|
||||
errno = EBADF;
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (output_stream), -1);
|
||||
|
||||
camel_stream_reset (output_stream, ex);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
}
|
||||
|
||||
camel_stream_reset (output_stream);
|
||||
|
||||
return camel_stream_write_to_stream(output_stream, stream);
|
||||
return camel_stream_write_to_stream (output_stream, stream, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_data_wrapper_write_to_stream:
|
||||
* @data_wrapper: a data wrapper
|
||||
* @stream: stream for data to be written to
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Writes the data content to @stream in a machine-independent format
|
||||
* appropriate for the data. It should be possible to construct an
|
||||
* equivalent data wrapper object later by passing this stream to
|
||||
* camel_data_construct_from_stream().
|
||||
*
|
||||
* Returns the number of bytes written, and -1 for error.
|
||||
* Return value: the number of bytes written, or -1 if an error occurs.
|
||||
**/
|
||||
int
|
||||
camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream)
|
||||
CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1);
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
|
||||
|
||||
return CDW_CLASS (data_wrapper)->write_to_stream (data_wrapper, stream);
|
||||
return CDW_CLASS (data_wrapper)->write_to_stream (data_wrapper,
|
||||
stream, ex);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@ -71,7 +71,8 @@ typedef struct {
|
||||
GMimeContentField *mime_type_field);
|
||||
|
||||
int (*write_to_stream) (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream);
|
||||
CamelStream *stream,
|
||||
CamelException *ex);
|
||||
|
||||
int (*construct_from_stream) (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *);
|
||||
@ -87,7 +88,8 @@ GtkType camel_data_wrapper_get_type (void);
|
||||
CamelDataWrapper *camel_data_wrapper_new (void);
|
||||
|
||||
int camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream);
|
||||
CamelStream *stream,
|
||||
CamelException *ex);
|
||||
void camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
|
||||
const gchar *mime_type);
|
||||
gchar * camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper);
|
||||
|
||||
@ -153,7 +153,8 @@ camel_exception_set (CamelException *ex,
|
||||
* camel_exception_setv: set an exception
|
||||
* @ex: exception object
|
||||
* @id: exception id
|
||||
* @format: format of the description string. The format string is used as in printf().
|
||||
* @format: format of the description string. The format string is
|
||||
* used as in printf().
|
||||
*
|
||||
* Set the value of an exception. The exception id is
|
||||
* a unique number representing the exception. The
|
||||
@ -162,6 +163,9 @@ camel_exception_set (CamelException *ex,
|
||||
* In this version, the string is created from the format
|
||||
* string and the variable argument list.
|
||||
*
|
||||
* It is safe to say:
|
||||
* camel_exception_setv (ex, ..., camel_exception_get_description (ex), ...);
|
||||
*
|
||||
* When @ex is NULL, nothing is done, this routine
|
||||
* simply returns.
|
||||
*
|
||||
|
||||
@ -79,7 +79,7 @@ void camel_exception_xfer (CamelException *ex_dst,
|
||||
ExceptionId camel_exception_get_id (CamelException *ex);
|
||||
const gchar * camel_exception_get_description (CamelException *ex);
|
||||
|
||||
|
||||
#define camel_exception_is_set(ex) (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -66,7 +66,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
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 int write_to_stream (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream, CamelException *ex);
|
||||
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);
|
||||
@ -536,7 +537,8 @@ construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp)
|
||||
}
|
||||
|
||||
static int
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelMimeMessage *mm = CAMEL_MIME_MESSAGE (data_wrapper);
|
||||
|
||||
@ -554,11 +556,11 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
camel_mime_message_set_subject(mm, "No Subject");
|
||||
}
|
||||
|
||||
/* FIXME: "To" header needs to be set explcitly as well ... */
|
||||
/* FIXME: "To" header needs to be set explicitly as well ... */
|
||||
|
||||
camel_medium_set_header((CamelMedium *)mm, "Mime-Version", "1.0");
|
||||
|
||||
return 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, ex);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "camel-mime-filter.h"
|
||||
#include "camel-stream.h"
|
||||
#include "camel-seekable-stream.h"
|
||||
#include "camel-exception.h"
|
||||
|
||||
#define r(x)
|
||||
#define h(x)
|
||||
@ -208,6 +209,7 @@ struct _header_scan_state {
|
||||
|
||||
int fd; /* input for a fd input */
|
||||
CamelStream *stream; /* or for a stream */
|
||||
CamelException *ex; /* exception for the stream */
|
||||
|
||||
/* for scanning input buffers */
|
||||
char *realbuf; /* the real buffer, SCAN_HEAD*2 + SCAN_BUF bytes */
|
||||
@ -824,7 +826,8 @@ folder_read(struct _header_scan_state *s)
|
||||
memcpy(s->inbuf, s->inptr, inoffset);
|
||||
}
|
||||
if (s->stream) {
|
||||
len = camel_stream_read(s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset);
|
||||
len = camel_stream_read(s->stream, s->inbuf+inoffset,
|
||||
SCAN_BUF-inoffset, s->ex);
|
||||
} else {
|
||||
len = read(s->fd, s->inbuf+inoffset, SCAN_BUF-inoffset);
|
||||
}
|
||||
@ -869,7 +872,7 @@ folder_seek(struct _header_scan_state *s, off_t offset, int whence)
|
||||
if (CAMEL_IS_SEEKABLE_STREAM(s->stream)) {
|
||||
/* NOTE: assumes whence seekable stream == whence libc, which is probably
|
||||
the case (or bloody well should've been) */
|
||||
newoffset = camel_seekable_stream_seek((CamelSeekableStream *)s->stream, offset, whence);
|
||||
newoffset = camel_seekable_stream_seek((CamelSeekableStream *)s->stream, offset, whence, s->ex);
|
||||
} else {
|
||||
newoffset = -1;
|
||||
errno = EINVAL;
|
||||
@ -886,7 +889,7 @@ folder_seek(struct _header_scan_state *s, off_t offset, int whence)
|
||||
s->inptr = s->inbuf;
|
||||
s->inend = s->inbuf;
|
||||
if (s->stream)
|
||||
len = camel_stream_read(s->stream, s->inbuf, SCAN_BUF);
|
||||
len = camel_stream_read(s->stream, s->inbuf, SCAN_BUF, s->ex);
|
||||
else
|
||||
len = read(s->fd, s->inbuf, SCAN_BUF);
|
||||
if (len>=0) {
|
||||
@ -1353,8 +1356,10 @@ folder_scan_close(struct _header_scan_state *s)
|
||||
folder_pull_part(s);
|
||||
if (s->fd != -1)
|
||||
close(s->fd);
|
||||
if (s->stream)
|
||||
if (s->stream) {
|
||||
gtk_object_unref((GtkObject *)s->stream);
|
||||
camel_exception_free(s->ex);
|
||||
}
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
@ -1368,6 +1373,7 @@ folder_scan_init(void)
|
||||
|
||||
s->fd = -1;
|
||||
s->stream = NULL;
|
||||
s->ex = NULL;
|
||||
|
||||
s->outbuf = g_malloc(1024);
|
||||
s->outptr = s->outbuf;
|
||||
@ -1415,6 +1421,8 @@ folder_scan_init_with_fd(struct _header_scan_state *s, int fd)
|
||||
if (s->stream) {
|
||||
gtk_object_unref((GtkObject *)s->stream);
|
||||
s->stream = NULL;
|
||||
camel_exception_free(s->ex);
|
||||
s->ex = NULL;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
@ -1426,9 +1434,11 @@ static int
|
||||
folder_scan_init_with_stream(struct _header_scan_state *s, CamelStream *stream)
|
||||
{
|
||||
int len;
|
||||
CamelException *ex;
|
||||
|
||||
len = camel_stream_read(stream, s->inbuf, SCAN_BUF);
|
||||
if (len>=0) {
|
||||
ex = camel_exception_new();
|
||||
len = camel_stream_read(stream, s->inbuf, SCAN_BUF, ex);
|
||||
if (!camel_exception_is_set (ex)) {
|
||||
s->inend = s->inbuf+len;
|
||||
s->inptr = s->inbuf;
|
||||
s->inend[0] = '\n';
|
||||
@ -1436,12 +1446,16 @@ folder_scan_init_with_stream(struct _header_scan_state *s, CamelStream *stream)
|
||||
gtk_object_unref((GtkObject *)s->stream);
|
||||
s->stream = stream;
|
||||
gtk_object_ref((GtkObject *)stream);
|
||||
if (s->ex)
|
||||
camel_exception_free(s->ex);
|
||||
s->ex = ex;
|
||||
if (s->fd != -1) {
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
camel_exception_free (ex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "camel-stream-mem.h"
|
||||
#include "camel-stream-filter.h"
|
||||
#include "camel-mime-filter-basic.h"
|
||||
#include "camel-exception.h"
|
||||
|
||||
#define d(x)
|
||||
|
||||
@ -66,7 +67,8 @@ static void finalize (GtkObject *object);
|
||||
|
||||
/* from CamelDataWrapper */
|
||||
static int write_to_stream (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream);
|
||||
CamelStream *stream,
|
||||
CamelException *ex);
|
||||
static int construct_from_stream (CamelDataWrapper *dw, CamelStream *s);
|
||||
|
||||
/* from CamelMedia */
|
||||
@ -478,12 +480,13 @@ set_content_object (CamelMedium *medium, CamelDataWrapper *content)
|
||||
/**********************************************************************/
|
||||
|
||||
static int
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelMimePart *mp = CAMEL_MIME_PART (data_wrapper);
|
||||
CamelMedium *medium = CAMEL_MEDIUM (data_wrapper);
|
||||
CamelDataWrapper *content;
|
||||
int total = 0, count;
|
||||
int total = 0;
|
||||
|
||||
d(printf("mime_part::write_to_stream\n"));
|
||||
|
||||
@ -494,16 +497,19 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
if (mp->headers) {
|
||||
struct _header_raw *h = mp->headers;
|
||||
while (h) {
|
||||
if ( (count = camel_stream_write_strings (stream, h->name, isspace(h->value[0])?":":": ", h->value, "\n", NULL) ) == -1 )
|
||||
total += camel_stream_printf (stream, ex, "%s%s%s\n",
|
||||
h->name,
|
||||
isspace(h->value[0]) ? ":" : ": ",
|
||||
h->value);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
total += count;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (count = camel_stream_write_string(stream,"\n")) == -1)
|
||||
total += camel_stream_write (stream, "\n", 1, ex);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
total += count;
|
||||
|
||||
content = camel_medium_get_content_object (medium);
|
||||
if (content) {
|
||||
@ -531,13 +537,11 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
}
|
||||
|
||||
#endif
|
||||
if ( (count = camel_data_wrapper_write_to_stream(content, stream)) == -1 )
|
||||
total = -1;
|
||||
else
|
||||
total += count;
|
||||
|
||||
total += camel_data_wrapper_write_to_stream (content, stream, ex);
|
||||
if (filter_stream)
|
||||
gtk_object_unref((GtkObject *)filter_stream);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
} else {
|
||||
g_warning("No content for medium, nothing to write");
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "camel-stream-mem.h"
|
||||
#include "camel-multipart.h"
|
||||
#include "camel-mime-part.h"
|
||||
#include "camel-exception.h"
|
||||
|
||||
#define d(x)
|
||||
|
||||
@ -50,7 +51,8 @@ static void set_boundary (CamelMultipart *multipart,
|
||||
gchar *boundary);
|
||||
static const gchar * get_boundary (CamelMultipart *multipart);
|
||||
static int write_to_stream (CamelDataWrapper *data_wrapper,
|
||||
CamelStream *stream);
|
||||
CamelStream *stream,
|
||||
CamelException *ex);
|
||||
static void finalize (GtkObject *object);
|
||||
|
||||
static CamelDataWrapperClass *parent_class = NULL;
|
||||
@ -404,18 +406,19 @@ camel_multipart_get_boundary (CamelMultipart *multipart)
|
||||
|
||||
/* this is MIME specific, doesn't belong here really */
|
||||
static int
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
|
||||
const gchar *boundary;
|
||||
int total = 0, count;
|
||||
int total = 0;
|
||||
GList *node;
|
||||
|
||||
/* get the bundary text */
|
||||
boundary = camel_multipart_get_boundary (multipart);
|
||||
|
||||
/* we cannot write a multipart without a boundary string */
|
||||
g_return_val_if_fail (boundary, -1);
|
||||
g_return_val_if_fail (boundary && *boundary, -1);
|
||||
|
||||
/*
|
||||
* write the preface text (usually something like
|
||||
@ -423,39 +426,40 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
* your mail client probably doesn't support ...."
|
||||
*/
|
||||
if (multipart->preface) {
|
||||
count = camel_stream_write_strings (stream, multipart->preface, NULL);
|
||||
if (count == -1)
|
||||
total += camel_stream_write_string (stream,
|
||||
multipart->preface, ex);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
total += count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, write all the parts, separated by the boundary
|
||||
* delimiter
|
||||
*/
|
||||
if (boundary==NULL || (boundary[0] == '\0'))
|
||||
g_warning ("Multipart boundary is zero length\n");
|
||||
|
||||
node = multipart->parts;
|
||||
while (node) {
|
||||
if ( (count = camel_stream_write_strings (stream, "\n--", boundary?boundary:"", "\n", NULL) ) == -1 )
|
||||
total += camel_stream_printf (stream, ex, "\n--%s\n",
|
||||
boundary);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
total += count;
|
||||
if ( (count = camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (node->data), stream)) == -1 )
|
||||
|
||||
total += camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (node->data), stream, ex);
|
||||
if (camel_exception_is_set (ex));
|
||||
return -1;
|
||||
total += count;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
/* write the terminating boudary delimiter */
|
||||
if ( ( count = camel_stream_write_strings (stream, "\n--", boundary, "--\n", NULL) ) == -1 )
|
||||
total += camel_stream_printf (stream, ex, "\n--%s--\n", boundary);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
total += count;
|
||||
|
||||
/* and finally the postface - it is NOT fatal if this fails */
|
||||
|
||||
/* and finally the postface */
|
||||
if (multipart->postface) {
|
||||
if ( ( count = camel_stream_write_strings (stream, multipart->postface, NULL) ) != -1 )
|
||||
total += count;
|
||||
total += camel_stream_write_string (stream,
|
||||
multipart->postface, ex);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return total;
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
|
||||
/*
|
||||
*
|
||||
* Author :
|
||||
/*
|
||||
* Author:
|
||||
* Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -24,31 +23,31 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "camel-seekable-stream.h"
|
||||
|
||||
static CamelStreamClass *parent_class=NULL;
|
||||
|
||||
static CamelStreamClass *parent_class = NULL;
|
||||
|
||||
/* Returns the class for a CamelSeekableStream */
|
||||
#define CSS_CLASS(so) CAMEL_SEEKABLE_STREAM_CLASS (GTK_OBJECT(so)->klass)
|
||||
|
||||
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 off_t seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex);
|
||||
static off_t stream_tell (CamelSeekableStream *stream);
|
||||
static void reset (CamelStream *stream, CamelException *ex);
|
||||
static void set_bounds (CamelSeekableStream *stream, off_t start, off_t end,
|
||||
CamelException *ex);
|
||||
|
||||
|
||||
static void
|
||||
camel_seekable_stream_class_init (CamelSeekableStreamClass *camel_seekable_stream_class)
|
||||
{
|
||||
CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_seekable_stream_class);
|
||||
CamelStreamClass *camel_stream_class =
|
||||
CAMEL_STREAM_CLASS (camel_seekable_stream_class);
|
||||
|
||||
parent_class = gtk_type_class (camel_stream_get_type ());
|
||||
|
||||
|
||||
/* seekable stream methods */
|
||||
camel_seekable_stream_class->seek = seek;
|
||||
camel_seekable_stream_class->tell = stream_tell;
|
||||
@ -71,9 +70,9 @@ GtkType
|
||||
camel_seekable_stream_get_type (void)
|
||||
{
|
||||
static GtkType camel_seekable_stream_type = 0;
|
||||
|
||||
if (!camel_seekable_stream_type) {
|
||||
GtkTypeInfo camel_seekable_stream_info =
|
||||
|
||||
if (!camel_seekable_stream_type) {
|
||||
GtkTypeInfo camel_seekable_stream_info =
|
||||
{
|
||||
"CamelSeekableStream",
|
||||
sizeof (CamelSeekableStream),
|
||||
@ -84,19 +83,20 @@ camel_seekable_stream_get_type (void)
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
|
||||
camel_seekable_stream_type = gtk_type_unique (camel_stream_get_type (), &camel_seekable_stream_info);
|
||||
}
|
||||
|
||||
|
||||
return camel_seekable_stream_type;
|
||||
}
|
||||
|
||||
|
||||
static off_t
|
||||
seek (CamelSeekableStream *stream,
|
||||
off_t offset,
|
||||
CamelStreamSeekPolicy policy)
|
||||
seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy, CamelException *ex)
|
||||
{
|
||||
g_warning ("CamelSeekableStream::seek called on default implementation \n");
|
||||
g_warning ("CamelSeekableStream::seek called on default "
|
||||
"implementation\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -105,7 +105,8 @@ seek (CamelSeekableStream *stream,
|
||||
* @stream: a CamelStream object.
|
||||
* @offset: offset value
|
||||
* @policy: what to do with the offset
|
||||
*
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Seek to the specified position in @stream.
|
||||
*
|
||||
* If @policy is CAMEL_STREAM_SET, seeks to @offset.
|
||||
@ -117,78 +118,88 @@ seek (CamelSeekableStream *stream,
|
||||
* @offset.
|
||||
*
|
||||
* Regardless of @policy, the stream's final position will be clamped
|
||||
* to the range specified by its lower and upper bounds.
|
||||
*
|
||||
* to the range specified by its lower and upper bounds, and the
|
||||
* stream's eos state will be updated.
|
||||
*
|
||||
* Return value: new position, -1 if operation failed.
|
||||
**/
|
||||
off_t
|
||||
camel_seekable_stream_seek (CamelSeekableStream *stream,
|
||||
off_t offset,
|
||||
CamelStreamSeekPolicy policy)
|
||||
camel_seekable_stream_seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex)
|
||||
{
|
||||
return CSS_CLASS (stream)->seek (stream, offset, policy);
|
||||
g_return_val_if_fail (CAMEL_IS_SEEKABLE_STREAM (stream), -1);
|
||||
|
||||
return CSS_CLASS (stream)->seek (stream, offset, policy, ex);
|
||||
}
|
||||
|
||||
|
||||
static off_t
|
||||
stream_tell(CamelSeekableStream *stream)
|
||||
stream_tell (CamelSeekableStream *stream)
|
||||
{
|
||||
return stream->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_seekable_stream_tell: get the position of a stream
|
||||
* @stream: seekable stream object
|
||||
*
|
||||
* camel_seekable_stream_tell:
|
||||
* @stream: seekable stream object
|
||||
*
|
||||
* Get the current position of a seekable stream.
|
||||
*
|
||||
*
|
||||
* Return value: the position.
|
||||
**/
|
||||
off_t
|
||||
camel_seekable_stream_tell (CamelSeekableStream *stream)
|
||||
{
|
||||
g_return_val_if_fail (CAMEL_IS_SEEKABLE_STREAM (stream), -1);
|
||||
|
||||
return CSS_CLASS (stream)->tell (stream);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_bounds (CamelSeekableStream *stream, off_t start, off_t end)
|
||||
set_bounds (CamelSeekableStream *stream, off_t start, off_t end,
|
||||
CamelException *ex)
|
||||
{
|
||||
/* 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_seek (stream, start, CAMEL_STREAM_SET, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_seekable_stream_set_bounds:
|
||||
* @stream:
|
||||
* @start:
|
||||
* @end:
|
||||
*
|
||||
* @stream: a seekable stream
|
||||
* @start: the first valid position
|
||||
* @end: the first invalid position, or CAMEL_STREAM_UNBOUND
|
||||
*
|
||||
* 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)
|
||||
camel_seekable_stream_set_bounds (CamelSeekableStream *stream,
|
||||
off_t start, off_t end, CamelException *ex)
|
||||
{
|
||||
CSS_CLASS (stream)->set_bounds (stream, start, end);
|
||||
g_return_if_fail (CAMEL_IS_SEEKABLE_STREAM (stream));
|
||||
g_return_if_fail (end == CAMEL_STREAM_UNBOUND || end >= start);
|
||||
|
||||
CSS_CLASS (stream)->set_bounds (stream, start, end, ex);
|
||||
}
|
||||
|
||||
/* a default implementation of reset for seekable streams */
|
||||
static void
|
||||
reset (CamelStream *stream)
|
||||
static void
|
||||
reset (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
CamelSeekableStream *seekable_stream;
|
||||
|
||||
g_assert (stream);
|
||||
seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
|
||||
|
||||
camel_seekable_stream_seek (seekable_stream, seekable_stream->bound_start, CAMEL_STREAM_SET);
|
||||
camel_seekable_stream_seek (seekable_stream,
|
||||
seekable_stream->bound_start,
|
||||
CAMEL_STREAM_SET, ex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* camel-stream-fs.h :stream based on unix filesystem */
|
||||
|
||||
/*
|
||||
*
|
||||
* Author :
|
||||
/*
|
||||
* Author:
|
||||
* Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -64,22 +63,28 @@ struct _CamelSeekableStream
|
||||
|
||||
typedef struct {
|
||||
CamelStreamClass parent_class;
|
||||
|
||||
/* Virtual methods */
|
||||
off_t (*seek) (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy);
|
||||
|
||||
/* Virtual methods */
|
||||
off_t (*seek) (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex);
|
||||
off_t (*tell) (CamelSeekableStream *stream);
|
||||
void (*set_bounds) (CamelSeekableStream *stream, off_t start, off_t end);
|
||||
void (*set_bounds) (CamelSeekableStream *stream,
|
||||
off_t start, off_t end, CamelException *ex);
|
||||
} CamelSeekableStreamClass;
|
||||
|
||||
/* Standard Gtk function */
|
||||
GtkType camel_seekable_stream_get_type (void);
|
||||
|
||||
/* public methods */
|
||||
off_t camel_seekable_stream_seek (CamelSeekableStream *stream,
|
||||
off_t offset,
|
||||
CamelStreamSeekPolicy policy);
|
||||
off_t camel_seekable_stream_tell (CamelSeekableStream *stream);
|
||||
void camel_seekable_stream_set_bounds (CamelSeekableStream *, off_t, off_t);
|
||||
off_t camel_seekable_stream_seek (CamelSeekableStream *stream,
|
||||
off_t offset,
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex);
|
||||
off_t camel_seekable_stream_tell (CamelSeekableStream *stream);
|
||||
void camel_seekable_stream_set_bounds (CamelSeekableStream *,
|
||||
off_t, off_t,
|
||||
CamelException *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -23,34 +23,39 @@
|
||||
*/
|
||||
#include <config.h>
|
||||
#include "camel-seekable-substream.h"
|
||||
#include "camel-exception.h"
|
||||
|
||||
static CamelSeekableStreamClass *parent_class = NULL;
|
||||
|
||||
/* Returns the class for a CamelSeekableSubStream */
|
||||
#define CSS_CLASS(so) CAMEL_SEEKABLE_SUBSTREAM_CLASS (GTK_OBJECT(so)->klass)
|
||||
|
||||
static gint 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 int stream_read (CamelStream *stream,
|
||||
char *buffer, unsigned int n,
|
||||
CamelException *ex);
|
||||
static int stream_write (CamelStream *stream,
|
||||
const char *buffer,
|
||||
unsigned int n,
|
||||
CamelException *ex);
|
||||
static void stream_flush (CamelStream *stream,
|
||||
CamelException *ex);
|
||||
static gboolean eos (CamelStream *stream);
|
||||
static off_t stream_seek (CamelSeekableStream *stream,
|
||||
off_t offset,
|
||||
CamelStreamSeekPolicy policy);
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex);
|
||||
static void finalize (GtkObject *object);
|
||||
|
||||
static void init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream,
|
||||
CamelSeekableStream *parent_stream,
|
||||
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 ());
|
||||
|
||||
@ -104,19 +109,6 @@ finalize (GtkObject *object)
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
init_with_seekable_stream_and_bounds (CamelSeekableSubstream *seekable_substream,
|
||||
CamelSeekableStream *parent_stream,
|
||||
off_t start, off_t end)
|
||||
{
|
||||
/* Store the parent stream. */
|
||||
seekable_substream->parent_stream = parent_stream;
|
||||
gtk_object_ref (GTK_OBJECT (parent_stream));
|
||||
|
||||
/* Set the bound of the substream. */
|
||||
camel_seekable_stream_set_bounds ((CamelSeekableStream *)seekable_substream, start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_seekable_substream_new_with_seekable_stream_and_bounds:
|
||||
* @parent_stream: a seekable parent stream
|
||||
@ -139,6 +131,7 @@ camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStrea
|
||||
off_t start, off_t end)
|
||||
{
|
||||
CamelSeekableSubstream *seekable_substream;
|
||||
CamelException ex;
|
||||
|
||||
g_return_val_if_fail (CAMEL_IS_SEEKABLE_STREAM (parent_stream), NULL);
|
||||
|
||||
@ -146,46 +139,56 @@ camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStrea
|
||||
seekable_substream = gtk_type_new (camel_seekable_substream_get_type ());
|
||||
|
||||
/* Initialize it. */
|
||||
init_with_seekable_stream_and_bounds (seekable_substream,
|
||||
parent_stream,
|
||||
start, end);
|
||||
seekable_substream->parent_stream = parent_stream;
|
||||
gtk_object_ref (GTK_OBJECT (parent_stream));
|
||||
|
||||
/* Set the bound of the substream. We can ignore any possible error
|
||||
* here, because if we fail to seek now, it will try again later.
|
||||
*/
|
||||
camel_exception_init (&ex);
|
||||
camel_seekable_stream_set_bounds ((CamelSeekableStream *)seekable_substream, start, end, &ex);
|
||||
camel_exception_clear (&ex);
|
||||
|
||||
return CAMEL_STREAM (seekable_substream);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parent_reset (CamelSeekableSubstream *seekable_substream)
|
||||
parent_reset (CamelSeekableSubstream *seekable_substream,
|
||||
CamelSeekableStream *parent, CamelException *ex)
|
||||
{
|
||||
CamelSeekableStream *parent, *seekable_stream = CAMEL_SEEKABLE_STREAM (seekable_substream);
|
||||
CamelSeekableStream *seekable_stream =
|
||||
CAMEL_SEEKABLE_STREAM (seekable_substream);
|
||||
|
||||
parent = seekable_substream->parent_stream;
|
||||
|
||||
g_return_val_if_fail (parent != NULL, FALSE);
|
||||
|
||||
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 {
|
||||
if (camel_seekable_stream_tell (parent) == seekable_stream->position)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
camel_seekable_stream_seek (parent, seekable_stream->position,
|
||||
CAMEL_STREAM_SET, ex);
|
||||
return !camel_exception_is_set (ex);
|
||||
}
|
||||
|
||||
static gint
|
||||
stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
static int
|
||||
stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelSeekableStream *parent;
|
||||
CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
|
||||
CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream);
|
||||
CamelSeekableSubstream *seekable_substream =
|
||||
CAMEL_SEEKABLE_SUBSTREAM (stream);
|
||||
int v;
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
parent = seekable_substream->parent_stream;
|
||||
|
||||
/* Go to our position in the parent stream. */
|
||||
if (!parent_reset (seekable_substream)) {
|
||||
if (!parent_reset (seekable_substream, parent, ex)) {
|
||||
stream->eos = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute how much byte should be read. */
|
||||
/* Compute how many bytes should be read. */
|
||||
if (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND)
|
||||
n = MIN (seekable_stream->bound_end - seekable_stream->position, n);
|
||||
|
||||
@ -194,7 +197,7 @@ stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
v = camel_stream_read (CAMEL_STREAM (seekable_substream->parent_stream), buffer, n);
|
||||
v = camel_stream_read (CAMEL_STREAM (parent), buffer, n, ex);
|
||||
|
||||
/* ignore <0 - its an error, let the caller deal */
|
||||
if (v > 0)
|
||||
@ -203,8 +206,9 @@ stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
return v;
|
||||
}
|
||||
|
||||
static gint
|
||||
stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
static int
|
||||
stream_write (CamelStream *stream, const char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
/* NOT VALID ON SEEKABLE SUBSTREAM */
|
||||
/* Well, its entirely valid, just not implemented */
|
||||
@ -214,7 +218,7 @@ stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
}
|
||||
|
||||
static void
|
||||
stream_flush (CamelStream *stream)
|
||||
stream_flush (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
/* NOT VALID ON SEEKABLE SUBSTREAM */
|
||||
g_warning ("CamelSeekableSubstream:: seekable substream doesn't "
|
||||
@ -224,37 +228,41 @@ stream_flush (CamelStream *stream)
|
||||
static gboolean
|
||||
eos (CamelStream *stream)
|
||||
{
|
||||
CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream);
|
||||
CamelSeekableSubstream *seekable_substream =
|
||||
CAMEL_SEEKABLE_SUBSTREAM (stream);
|
||||
CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
|
||||
guint32 substream_len;
|
||||
CamelSeekableStream *parent;
|
||||
CamelException ex;
|
||||
gboolean eos;
|
||||
|
||||
g_assert (stream);
|
||||
|
||||
if (stream->eos) {
|
||||
if (stream->eos)
|
||||
eos = TRUE;
|
||||
} else {
|
||||
parent_reset (seekable_substream);
|
||||
else {
|
||||
parent = seekable_substream->parent_stream;
|
||||
camel_exception_init (&ex);
|
||||
parent_reset (seekable_substream, parent, &ex);
|
||||
if (camel_exception_is_set (&ex)) {
|
||||
camel_exception_clear (&ex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
eos = camel_stream_eos (CAMEL_STREAM (seekable_substream->parent_stream));
|
||||
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);
|
||||
eos = camel_stream_eos (CAMEL_STREAM (parent));
|
||||
if (!eos && (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND)) {
|
||||
eos = seekable_stream->position >= seekable_stream->bound_end;
|
||||
}
|
||||
}
|
||||
|
||||
return eos;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
CamelStreamSeekPolicy policy, CamelException *ex)
|
||||
{
|
||||
CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (seekable_stream);
|
||||
CamelStream *stream = (CamelStream *)seekable_stream;
|
||||
CamelSeekableSubstream *seekable_substream =
|
||||
CAMEL_SEEKABLE_SUBSTREAM (seekable_stream);
|
||||
CamelStream *stream = CAMEL_STREAM (seekable_stream);
|
||||
off_t real_offset = 0;
|
||||
off_t parent_pos;
|
||||
|
||||
stream->eos = FALSE;
|
||||
|
||||
@ -268,20 +276,13 @@ stream_seek (CamelSeekableStream *seekable_stream, off_t offset,
|
||||
break;
|
||||
|
||||
case CAMEL_STREAM_END:
|
||||
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);
|
||||
if (parent_pos == -1)
|
||||
return -1;
|
||||
real_offset = parent_pos;
|
||||
}
|
||||
real_offset = camel_seekable_stream_seek (seekable_substream->parent_stream,
|
||||
offset,
|
||||
CAMEL_STREAM_END,
|
||||
ex);
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND)
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* camel-seekable-substream.h : stream
|
||||
*
|
||||
* Author :
|
||||
/* camel-seekable-substream.h: stream that piggybacks on another stream */
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
*
|
||||
* Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
|
||||
@ -50,10 +51,6 @@ struct _CamelSeekableSubstream
|
||||
typedef struct {
|
||||
CamelSeekableStreamClass parent_class;
|
||||
|
||||
/* Virtual methods */
|
||||
void (*init_with_seekable_stream_and_bounds) (CamelSeekableSubstream *seekable_substream,
|
||||
CamelSeekableStream *parent_stream,
|
||||
off_t start, off_t end);
|
||||
} CamelSeekableSubstreamClass;
|
||||
|
||||
/* Standard Gtk function */
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -25,12 +25,13 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "camel-stream-buffer.h"
|
||||
#include "camel-exception.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static CamelStreamBufferClass *parent_class=NULL;
|
||||
static CamelStreamBufferClass *parent_class = NULL;
|
||||
|
||||
enum {
|
||||
BUF_USER = 1<<0, /* user-supplied buffer, do not free */
|
||||
@ -38,9 +39,11 @@ enum {
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
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 int stream_read (CamelStream *stream, char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
static int stream_write (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
static void stream_flush (CamelStream *stream, CamelException *ex);
|
||||
static gboolean stream_eos (CamelStream *stream);
|
||||
|
||||
static void finalize (GtkObject *object);
|
||||
@ -56,7 +59,7 @@ camel_stream_buffer_class_init (CamelStreamBufferClass *camel_stream_buffer_clas
|
||||
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_stream_buffer_class);
|
||||
|
||||
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;
|
||||
@ -90,10 +93,10 @@ GtkType
|
||||
camel_stream_buffer_get_type (void)
|
||||
{
|
||||
static GtkType camel_stream_buffer_type = 0;
|
||||
|
||||
|
||||
gdk_threads_enter ();
|
||||
if (!camel_stream_buffer_type) {
|
||||
GtkTypeInfo camel_stream_buffer_info =
|
||||
GtkTypeInfo camel_stream_buffer_info =
|
||||
{
|
||||
"CamelStreamBuffer",
|
||||
sizeof (CamelStreamBuffer),
|
||||
@ -104,7 +107,7 @@ camel_stream_buffer_get_type (void)
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
|
||||
camel_stream_buffer_type = gtk_type_unique (camel_stream_get_type (), &camel_stream_buffer_info);
|
||||
}
|
||||
gdk_threads_leave ();
|
||||
@ -112,19 +115,19 @@ camel_stream_buffer_get_type (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
static void
|
||||
destroy (GtkObject *object)
|
||||
{
|
||||
CamelStreamBuffer *stream_buffer = CAMEL_STREAM_BUFFER (object);
|
||||
|
||||
|
||||
/* NOP to remove warnings */
|
||||
stream_buffer->buf = stream_buffer->buf;
|
||||
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->destroy (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
static void
|
||||
finalize (GtkObject *object)
|
||||
{
|
||||
CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (object);
|
||||
@ -134,7 +137,7 @@ finalize (GtkObject *object)
|
||||
}
|
||||
if (sbf->stream)
|
||||
gtk_object_unref(GTK_OBJECT(sbf->stream));
|
||||
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -176,14 +179,14 @@ init(CamelStreamBuffer *sbuf, CamelStream *s, CamelStreamBufferMode mode)
|
||||
* camel_stream_buffer_new:
|
||||
* @stream: Existing stream to buffer.
|
||||
* @mode: Operational mode of buffered stream.
|
||||
*
|
||||
*
|
||||
* Create a new buffered stream of another stream. A default
|
||||
* buffer size (1024 bytes), automatically managed will be used
|
||||
* for buffering.
|
||||
*
|
||||
* See camel_stream_buffer_new_with_vbuf() for details on the
|
||||
* @mode parameter.
|
||||
*
|
||||
*
|
||||
* Return value: A newly created buffered stream.
|
||||
**/
|
||||
CamelStream *
|
||||
@ -192,7 +195,7 @@ camel_stream_buffer_new (CamelStream *stream, CamelStreamBufferMode mode)
|
||||
CamelStreamBuffer *sbf;
|
||||
sbf = gtk_type_new (camel_stream_buffer_get_type ());
|
||||
CAMEL_STREAM_BUFFER_CLASS (GTK_OBJECT(sbf)->klass)->init (sbf, stream, mode);
|
||||
|
||||
|
||||
return CAMEL_STREAM (sbf);
|
||||
}
|
||||
|
||||
@ -202,7 +205,7 @@ camel_stream_buffer_new (CamelStream *stream, CamelStreamBufferMode mode)
|
||||
* @mode: Mode to buffer in.
|
||||
* @buf: Memory to use for buffering.
|
||||
* @size: Size of buffer to use.
|
||||
*
|
||||
*
|
||||
* Create a new stream which buffers another stream, @stream.
|
||||
*
|
||||
* The following values are available for @mode:
|
||||
@ -219,10 +222,10 @@ camel_stream_buffer_new (CamelStream *stream, CamelStreamBufferMode mode)
|
||||
*
|
||||
* CAMEL_STREAM_BUFFER_WRITE, Buffer in write mode.
|
||||
* CAMEL_STREAM_BUFFER_READ, Buffer in read mode.
|
||||
*
|
||||
*
|
||||
* Buffering can only be done in one direction for any
|
||||
* buffer instance.
|
||||
*
|
||||
*
|
||||
* If @buf is non-NULL, then use the memory pointed to
|
||||
* (for upto @size bytes) as the buffer for all buffering
|
||||
* operations. It is upto the application to free this buffer.
|
||||
@ -236,34 +239,25 @@ CamelStream *camel_stream_buffer_new_with_vbuf (CamelStream *stream, CamelStream
|
||||
CamelStreamBuffer *sbf;
|
||||
sbf = gtk_type_new (camel_stream_buffer_get_type ());
|
||||
CAMEL_STREAM_BUFFER_CLASS (GTK_OBJECT(sbf)->klass)->init_vbuf (sbf, stream, mode, buf, size);
|
||||
|
||||
return CAMEL_STREAM (sbf);
|
||||
|
||||
return CAMEL_STREAM (sbf);
|
||||
}
|
||||
|
||||
/**
|
||||
* _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
|
||||
stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
static int
|
||||
stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream);
|
||||
int bytes_read=1;
|
||||
int bytes_read = 1;
|
||||
int bytes_left;
|
||||
gchar *bptr = buffer;
|
||||
char *bptr = buffer;
|
||||
|
||||
g_return_val_if_fail( (sbf->mode & CAMEL_STREAM_BUFFER_MODE) == CAMEL_STREAM_BUFFER_READ, 0);
|
||||
|
||||
while (n && bytes_read>0) {
|
||||
while (n && bytes_read > 0) {
|
||||
bytes_left = sbf->end - sbf->ptr;
|
||||
if (bytes_left<n) {
|
||||
if (bytes_left>0) {
|
||||
if (bytes_left < n) {
|
||||
if (bytes_left > 0) {
|
||||
memcpy(bptr, sbf->ptr, bytes_left);
|
||||
n -= bytes_left;
|
||||
bptr += bytes_left;
|
||||
@ -271,13 +265,13 @@ stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
}
|
||||
/* if we are reading a lot, then read directly to the destination buffer */
|
||||
if (n >= sbf->size/3) {
|
||||
bytes_read = camel_stream_read(sbf->stream, bptr, n);
|
||||
bytes_read = camel_stream_read(sbf->stream, bptr, n, ex);
|
||||
if (bytes_read>0) {
|
||||
n -= bytes_read;
|
||||
bptr += bytes_read;
|
||||
}
|
||||
} else {
|
||||
bytes_read = camel_stream_read(sbf->stream, sbf->buf, sbf->size);
|
||||
bytes_read = camel_stream_read(sbf->stream, sbf->buf, sbf->size, ex);
|
||||
if (bytes_read>0) {
|
||||
sbf->ptr = sbf->buf;
|
||||
sbf->end = sbf->buf+bytes_read;
|
||||
@ -287,6 +281,8 @@ stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
n -= bytes_read;
|
||||
}
|
||||
}
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(bptr, sbf->ptr, bytes_left);
|
||||
sbf->ptr += n;
|
||||
@ -299,11 +295,12 @@ stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
static int
|
||||
stream_write (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex)
|
||||
{
|
||||
CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream);
|
||||
const gchar *bptr = buffer;
|
||||
const char *bptr = buffer;
|
||||
int bytes_written = 1;
|
||||
int bytes_left;
|
||||
|
||||
@ -315,11 +312,11 @@ stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
memcpy(sbf->ptr, bptr, bytes_left);
|
||||
n -= bytes_left;
|
||||
bptr += bytes_left;
|
||||
bytes_written = camel_stream_write(sbf->stream, sbf->buf, sbf->size);
|
||||
bytes_written = camel_stream_write(sbf->stream, sbf->buf, sbf->size, ex);
|
||||
sbf->ptr = sbf->buf;
|
||||
/* if we are writing a lot, write directly to the stream */
|
||||
if (n >= sbf->size/3) {
|
||||
bytes_written = camel_stream_write(sbf->stream, bptr, n);
|
||||
bytes_written = camel_stream_write(sbf->stream, bptr, n, ex);
|
||||
bytes_written = n;
|
||||
n -= bytes_written;
|
||||
bptr += bytes_written;
|
||||
@ -329,6 +326,8 @@ stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
bptr += n;
|
||||
n = 0;
|
||||
}
|
||||
if (camel_exception_is_set (ex))
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(sbf->ptr, bptr, n);
|
||||
sbf->ptr += n;
|
||||
@ -342,12 +341,12 @@ stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
|
||||
|
||||
static void
|
||||
stream_flush (CamelStream *stream)
|
||||
stream_flush (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream);
|
||||
|
||||
if ((sbf->mode & CAMEL_STREAM_BUFFER_MODE) == CAMEL_STREAM_BUFFER_WRITE) {
|
||||
int written = camel_stream_write(sbf->stream, sbf->buf, sbf->ptr-sbf->buf);
|
||||
int written = camel_stream_write(sbf->stream, sbf->buf, sbf->ptr-sbf->buf, ex);
|
||||
if (written > 0) {
|
||||
sbf->ptr += written;
|
||||
}
|
||||
@ -355,7 +354,8 @@ stream_flush (CamelStream *stream)
|
||||
/* nothing to do for read mode 'flush' */
|
||||
}
|
||||
|
||||
camel_stream_flush(sbf->stream);
|
||||
if (!camel_exception_is_set (ex))
|
||||
camel_stream_flush(sbf->stream, ex);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -371,17 +371,19 @@ stream_eos (CamelStream *stream)
|
||||
* @sbf: A CamelStreamBuffer.
|
||||
* @buf: Memory to write the string to.
|
||||
* @max: Maxmimum number of characters to store.
|
||||
*
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Read a line of characters up to the next newline character or
|
||||
* @max characters.
|
||||
*
|
||||
* If the newline character is encountered, then it will be
|
||||
* included in the buffer @buf. The buffer will be #NUL terminated.
|
||||
*
|
||||
* Return value: The number of characters read, or 0 for end of file or
|
||||
* file error.
|
||||
*
|
||||
* Return value: The number of characters read, or 0 for end of file.
|
||||
* If an error occurs, @ex will be set.
|
||||
**/
|
||||
int camel_stream_buffer_gets(CamelStreamBuffer *sbf, char *buf, int max)
|
||||
int camel_stream_buffer_gets(CamelStreamBuffer *sbf, char *buf,
|
||||
unsigned int max, CamelException *ex)
|
||||
{
|
||||
register char *outptr, *inptr, *inend, c, *outend;
|
||||
int bytes_read;
|
||||
@ -404,12 +406,13 @@ int camel_stream_buffer_gets(CamelStreamBuffer *sbf, char *buf, int max)
|
||||
if (outptr == outend)
|
||||
break;
|
||||
|
||||
bytes_read = camel_stream_read(sbf->stream, sbf->buf, sbf->size);
|
||||
bytes_read = camel_stream_read(sbf->stream, sbf->buf,
|
||||
sbf->size, ex);
|
||||
if (bytes_read>0) {
|
||||
inptr = sbf->ptr = sbf->buf;
|
||||
inend = sbf->end = sbf->buf + bytes_read;
|
||||
}
|
||||
} while (bytes_read>0);
|
||||
} while (bytes_read>0 && !camel_exception_is_set (ex));
|
||||
|
||||
sbf->ptr = inptr;
|
||||
if (outptr<=outend)
|
||||
@ -421,16 +424,17 @@ int camel_stream_buffer_gets(CamelStreamBuffer *sbf, char *buf, int max)
|
||||
/**
|
||||
* camel_stream_buffer_read_line: read a complete line from the stream
|
||||
* @sbf: A CamelStreamBuffer
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* This function reads a complete newline-terminated line from the stream
|
||||
* and returns it in allocated memory. The trailing newline (and carriage
|
||||
* return if any) are not included in the returned string.
|
||||
*
|
||||
* Return value: the line read, which the caller must free when done with,
|
||||
* or NULL on eof or error.
|
||||
* or NULL on eof. If an error occurs, @ex will be set.
|
||||
**/
|
||||
char *
|
||||
camel_stream_buffer_read_line (CamelStreamBuffer *sbf)
|
||||
camel_stream_buffer_read_line (CamelStreamBuffer *sbf, CamelException *ex)
|
||||
{
|
||||
char *buf, *p;
|
||||
int bufsiz, nread;
|
||||
@ -439,8 +443,9 @@ camel_stream_buffer_read_line (CamelStreamBuffer *sbf)
|
||||
p = buf = g_malloc (bufsiz);
|
||||
|
||||
while (1) {
|
||||
nread = camel_stream_buffer_gets (sbf, p, bufsiz - (p - buf));
|
||||
if (nread == 0) {
|
||||
nread = camel_stream_buffer_gets (sbf, p,
|
||||
bufsiz - (p - buf), ex);
|
||||
if (nread == 0 || camel_exception_is_set (ex)) {
|
||||
g_free (buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* camel-stream-buffer.h :stream which buffers another stream */
|
||||
|
||||
/*
|
||||
/*
|
||||
*
|
||||
* Author :
|
||||
* Author :
|
||||
* Michael Zucchi <notzed@helixcode.com>
|
||||
*
|
||||
* Copyright 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
|
||||
* 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.
|
||||
*
|
||||
@ -42,7 +42,7 @@ extern "C" {
|
||||
#define CAMEL_STREAM_BUFFER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_BUFFER_TYPE, CamelStreamBufferClass))
|
||||
#define CAMEL_IS_STREAM_BUFFER(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_BUFFER_TYPE))
|
||||
|
||||
typedef enum
|
||||
typedef enum
|
||||
{
|
||||
CAMEL_STREAM_BUFFER_BUFFER = 0,
|
||||
CAMEL_STREAM_BUFFER_NEWLINE,
|
||||
@ -59,9 +59,7 @@ struct _CamelStreamBuffer
|
||||
/* these are all of course, private */
|
||||
CamelStream *stream;
|
||||
|
||||
unsigned char *buf,
|
||||
*ptr,
|
||||
*end;
|
||||
unsigned char *buf, *ptr, *end;
|
||||
int size;
|
||||
|
||||
CamelStreamBufferMode mode;
|
||||
@ -69,33 +67,39 @@ struct _CamelStreamBuffer
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
CamelStreamClass parent_class;
|
||||
|
||||
/* Virtual methods */
|
||||
void (*init) (CamelStreamBuffer *stream_buffer, CamelStream *stream, CamelStreamBufferMode mode);
|
||||
void (*init_vbuf) (CamelStreamBuffer *stream_buffer, CamelStream *stream, CamelStreamBufferMode mode, char *buf, guint32 size);
|
||||
|
||||
/* Virtual methods */
|
||||
void (*init) (CamelStreamBuffer *stream_buffer, CamelStream *stream,
|
||||
CamelStreamBufferMode mode);
|
||||
void (*init_vbuf) (CamelStreamBuffer *stream_buffer,
|
||||
CamelStream *stream, CamelStreamBufferMode mode,
|
||||
char *buf, guint32 size);
|
||||
|
||||
} CamelStreamBufferClass;
|
||||
|
||||
|
||||
|
||||
/* Standard Gtk function */
|
||||
GtkType camel_stream_buffer_get_type (void);
|
||||
|
||||
|
||||
/* public methods */
|
||||
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_new (CamelStream *s,
|
||||
CamelStreamBufferMode mode);
|
||||
CamelStream *camel_stream_buffer_new_with_vbuf (CamelStream *s,
|
||||
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);
|
||||
int camel_stream_buffer_gets (CamelStreamBuffer *b, char *buf,
|
||||
unsigned int max, CamelException *ex);
|
||||
|
||||
char *camel_stream_buffer_read_line (CamelStreamBuffer *sbf);
|
||||
char *camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
|
||||
CamelException *ex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "camel-stream-filter.h"
|
||||
#include "camel-exception.h"
|
||||
|
||||
struct _filter {
|
||||
struct _filter *next;
|
||||
@ -47,11 +48,13 @@ struct _CamelStreamFilterPrivate {
|
||||
static void camel_stream_filter_class_init (CamelStreamFilterClass *klass);
|
||||
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 int do_read (CamelStream *stream, char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
static int do_write (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
static void do_flush (CamelStream *stream, CamelException *ex);
|
||||
static gboolean do_eos (CamelStream *stream);
|
||||
static void do_reset (CamelStream *stream);
|
||||
static void do_reset (CamelStream *stream, CamelException *ex);
|
||||
|
||||
static CamelStreamClass *camel_stream_filter_parent;
|
||||
|
||||
@ -212,7 +215,8 @@ camel_stream_filter_remove(CamelStreamFilter *filter, int id)
|
||||
}
|
||||
}
|
||||
|
||||
static gint do_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
static int
|
||||
do_read (CamelStream *stream, char *buffer, unsigned int n, CamelException *ex)
|
||||
{
|
||||
CamelStreamFilter *filter = (CamelStreamFilter *)stream;
|
||||
struct _CamelStreamFilterPrivate *p = _PRIVATE(filter);
|
||||
@ -224,7 +228,7 @@ static gint do_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
if (p->filteredlen<=0) {
|
||||
int presize = READ_SIZE;
|
||||
|
||||
size = camel_stream_read(filter->source, p->buffer, READ_SIZE);
|
||||
size = camel_stream_read(filter->source, p->buffer, READ_SIZE, ex);
|
||||
if (size<=0) {
|
||||
/* this is somewhat untested */
|
||||
if (camel_stream_eos(filter->source)) {
|
||||
@ -258,7 +262,8 @@ static gint do_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
return size;
|
||||
}
|
||||
|
||||
static gint do_write (CamelStream *stream, const gchar *buf, gint n)
|
||||
static int
|
||||
do_write (CamelStream *stream, const char *buf, unsigned int n, CamelException *ex)
|
||||
{
|
||||
CamelStreamFilter *filter = (CamelStreamFilter *)stream;
|
||||
struct _CamelStreamFilterPrivate *p = _PRIVATE(filter);
|
||||
@ -275,10 +280,11 @@ static gint do_write (CamelStream *stream, const gchar *buf, gint n)
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
return camel_stream_write(filter->source, buffer, n);
|
||||
return camel_stream_write(filter->source, buffer, n, ex);
|
||||
}
|
||||
|
||||
static void do_flush (CamelStream *stream)
|
||||
static void
|
||||
do_flush (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
CamelStreamFilter *filter = (CamelStreamFilter *)stream;
|
||||
struct _CamelStreamFilterPrivate *p = _PRIVATE(filter);
|
||||
@ -299,14 +305,13 @@ static void do_flush (CamelStream *stream)
|
||||
camel_mime_filter_complete(f->filter, buffer, len, presize, &buffer, &len, &presize);
|
||||
f = f->next;
|
||||
}
|
||||
if (camel_stream_write(filter->source, buffer, len) == -1) {
|
||||
g_warning("Flushing filter failed to write, no way to signal failure ...");
|
||||
}
|
||||
|
||||
return camel_stream_flush(filter->source);
|
||||
camel_stream_write(filter->source, buffer, len, ex);
|
||||
if (!camel_exception_is_set(ex))
|
||||
camel_stream_flush(filter->source, ex);
|
||||
}
|
||||
|
||||
static gboolean do_eos (CamelStream *stream)
|
||||
static gboolean
|
||||
do_eos (CamelStream *stream)
|
||||
{
|
||||
CamelStreamFilter *filter = (CamelStreamFilter *)stream;
|
||||
struct _CamelStreamFilterPrivate *p = _PRIVATE(filter);
|
||||
@ -317,27 +322,15 @@ static gboolean do_eos (CamelStream *stream)
|
||||
return camel_stream_eos(filter->source);
|
||||
}
|
||||
|
||||
static void do_close (CamelStream *stream)
|
||||
{
|
||||
CamelStreamFilter *filter = (CamelStreamFilter *)stream;
|
||||
struct _CamelStreamFilterPrivate *p = _PRIVATE(filter);
|
||||
|
||||
if (p->last_was_read == 0) {
|
||||
camel_stream_flush(stream);
|
||||
}
|
||||
|
||||
p->filteredlen = 0;
|
||||
/* camel_stream_close(filter->source);*/
|
||||
}
|
||||
|
||||
static void do_reset (CamelStream *stream)
|
||||
static void
|
||||
do_reset (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
CamelStreamFilter *filter = (CamelStreamFilter *)stream;
|
||||
struct _CamelStreamFilterPrivate *p = _PRIVATE(filter);
|
||||
struct _filter *f;
|
||||
|
||||
p->filteredlen = 0;
|
||||
camel_stream_reset(filter->source);
|
||||
camel_stream_reset(filter->source, ex);
|
||||
|
||||
/* and reset filters */
|
||||
f = p->filters;
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
/* -*- 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 */
|
||||
/*
|
||||
|
||||
/*
|
||||
* Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
* Michael Zucchi <notzed@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -22,8 +22,10 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "camel-stream-fs.h"
|
||||
#include "camel-exception.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -31,39 +33,34 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
static CamelSeekableStreamClass *parent_class=NULL;
|
||||
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 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 off_t stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy);
|
||||
static int stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex);
|
||||
static int stream_write (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
static void stream_flush (CamelStream *stream, CamelException *ex);
|
||||
static off_t stream_seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex);
|
||||
|
||||
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, 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)
|
||||
{
|
||||
CamelSeekableStreamClass *camel_seekable_stream_class = CAMEL_SEEKABLE_STREAM_CLASS (camel_stream_fs_class);
|
||||
CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_stream_fs_class);
|
||||
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_stream_fs_class);
|
||||
CamelSeekableStreamClass *camel_seekable_stream_class =
|
||||
CAMEL_SEEKABLE_STREAM_CLASS (camel_stream_fs_class);
|
||||
CamelStreamClass *camel_stream_class =
|
||||
CAMEL_STREAM_CLASS (camel_stream_fs_class);
|
||||
GtkObjectClass *gtk_object_class =
|
||||
GTK_OBJECT_CLASS (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;
|
||||
|
||||
|
||||
/* virtual method overload */
|
||||
camel_stream_class->read = stream_read;
|
||||
camel_stream_class->write = stream_write;
|
||||
@ -75,11 +72,10 @@ camel_stream_fs_class_init (CamelStreamFsClass *camel_stream_fs_class)
|
||||
}
|
||||
|
||||
static void
|
||||
camel_stream_fs_init (gpointer object, gpointer klass)
|
||||
camel_stream_fs_init (gpointer object, gpointer klass)
|
||||
{
|
||||
CamelStreamFs *stream = CAMEL_STREAM_FS (object);
|
||||
|
||||
stream->name = NULL;
|
||||
stream->fd = -1;
|
||||
}
|
||||
|
||||
@ -87,9 +83,9 @@ GtkType
|
||||
camel_stream_fs_get_type (void)
|
||||
{
|
||||
static GtkType camel_stream_fs_type = 0;
|
||||
|
||||
if (!camel_stream_fs_type) {
|
||||
GtkTypeInfo camel_stream_fs_info =
|
||||
|
||||
if (!camel_stream_fs_type) {
|
||||
GtkTypeInfo camel_stream_fs_info =
|
||||
{
|
||||
"CamelStreamFs",
|
||||
sizeof (CamelStreamFs),
|
||||
@ -100,225 +96,210 @@ camel_stream_fs_get_type (void)
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
|
||||
camel_stream_fs_type = gtk_type_unique (camel_seekable_stream_get_type (), &camel_stream_fs_info);
|
||||
}
|
||||
|
||||
|
||||
return camel_stream_fs_type;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
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);
|
||||
if (stream_fs->fd != -1)
|
||||
close (stream_fs->fd);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
init_with_fd (CamelStreamFs *stream_fs, int fd)
|
||||
{
|
||||
off_t offset;
|
||||
|
||||
stream_fs->fd = fd;
|
||||
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, off_t start, off_t end)
|
||||
{
|
||||
|
||||
CSFS_CLASS (stream_fs)->init_with_fd (stream_fs, fd);
|
||||
camel_seekable_stream_set_bounds((CamelSeekableStream *)stream_fs, start, end);
|
||||
}
|
||||
|
||||
static int
|
||||
init_with_name (CamelStreamFs *stream_fs, const gchar *name, int flags, int mode)
|
||||
{
|
||||
int fd;
|
||||
|
||||
g_assert(name);
|
||||
g_assert(stream_fs);
|
||||
|
||||
fd = open (name, flags, mode);
|
||||
if (fd==-1) {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
init_with_name_and_bounds (CamelStreamFs *stream_fs, const gchar *name, int flags, int mode,
|
||||
off_t start, off_t end)
|
||||
{
|
||||
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, int flags, int mode)
|
||||
{
|
||||
CamelStreamFs *stream_fs;
|
||||
stream_fs = gtk_type_new (camel_stream_fs_get_type ());
|
||||
if (CSFS_CLASS (stream_fs)->init_with_name (stream_fs, name, flags, mode) == -1) {
|
||||
gtk_object_unref (GTK_OBJECT (stream_fs));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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, int flags, int mode,
|
||||
off_t start, off_t end)
|
||||
{
|
||||
CamelStreamFs *stream_fs;
|
||||
stream_fs = gtk_type_new (camel_stream_fs_get_type ());
|
||||
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:
|
||||
* @fd: a file descriptor
|
||||
*
|
||||
* Returns a stream associated with the given file descriptor.
|
||||
* When the stream is destroyed, the file descriptor will be closed.
|
||||
*
|
||||
* Return value: the stream
|
||||
**/
|
||||
CamelStream *
|
||||
camel_stream_fs_new_with_fd (int fd)
|
||||
{
|
||||
CamelStreamFs *stream_fs;
|
||||
|
||||
off_t offset;
|
||||
|
||||
stream_fs = gtk_type_new (camel_stream_fs_get_type ());
|
||||
CSFS_CLASS (stream_fs)->init_with_fd (stream_fs, fd);
|
||||
|
||||
stream_fs->fd = fd;
|
||||
offset = lseek (fd, 0, SEEK_CUR);
|
||||
if (offset == -1)
|
||||
offset = 0;
|
||||
CAMEL_SEEKABLE_STREAM (stream_fs)->position = offset;
|
||||
|
||||
return CAMEL_STREAM (stream_fs);
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_stream_fs_new_with_fd_and_bounds:
|
||||
* @fd:
|
||||
* @inf_bound:
|
||||
* @sup_bound:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
* @fd: a file descriptor
|
||||
* @start: the first valid position in the file
|
||||
* @end: the first invalid position in the file, or CAMEL_STREAM_UNBOUND
|
||||
*
|
||||
* Returns a stream associated with the given file descriptor and bounds.
|
||||
* When the stream is destroyed, the file descriptor will be closed.
|
||||
*
|
||||
* Return value: the stream
|
||||
**/
|
||||
CamelStream *
|
||||
camel_stream_fs_new_with_fd_and_bounds (int fd, off_t start, off_t end)
|
||||
camel_stream_fs_new_with_fd_and_bounds (int fd, off_t start, off_t end,
|
||||
CamelException *ex)
|
||||
{
|
||||
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, start, end);
|
||||
|
||||
return CAMEL_STREAM (stream_fs);
|
||||
CamelStream *stream;
|
||||
|
||||
stream = camel_stream_fs_new_with_fd (fd);
|
||||
camel_seekable_stream_set_bounds (CAMEL_SEEKABLE_STREAM (stream),
|
||||
start, end, ex);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
static gint
|
||||
stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
/**
|
||||
* camel_stream_fs_new_with_name:
|
||||
* @name: a local filename
|
||||
* @flags: flags as in open(2)
|
||||
* @mode: a file mode
|
||||
* @ex: a CamelException.
|
||||
*
|
||||
* Creates a new CamelStream corresponding to the named file, flags,
|
||||
* and mode. If an error occurs, @ex will be set.
|
||||
*
|
||||
* Return value: the stream
|
||||
**/
|
||||
CamelStream *
|
||||
camel_stream_fs_new_with_name (const char *name, int flags, mode_t mode,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStream *stream;
|
||||
int fd;
|
||||
|
||||
fd = open (name, flags, mode);
|
||||
if (fd == -1) {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not open file %s: %s.",
|
||||
name, g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream = camel_stream_fs_new_with_fd (fd);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_stream_fs_new_with_name_and_bounds:
|
||||
* @name: a local filename
|
||||
* @flags: flags as in open(2)
|
||||
* @mode: a file mode
|
||||
* @start: the first valid position in the file
|
||||
* @end: the first invalid position in the file, or CAMEL_STREAM_UNBOUND
|
||||
* @ex: a CamelException.
|
||||
*
|
||||
* Creates a new CamelStream corresponding to the given arguments. If
|
||||
* an error occurs, @ex will be set.
|
||||
*
|
||||
* Return value: the stream
|
||||
**/
|
||||
CamelStream *
|
||||
camel_stream_fs_new_with_name_and_bounds (const char *name, int flags,
|
||||
mode_t mode, off_t start, off_t end,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStream *stream;
|
||||
|
||||
stream = camel_stream_fs_new_with_name (name, flags, mode, ex);
|
||||
if (camel_exception_is_set (ex))
|
||||
return NULL;
|
||||
|
||||
camel_seekable_stream_set_bounds (CAMEL_SEEKABLE_STREAM (stream),
|
||||
start, end, ex);
|
||||
if (camel_exception_is_set (ex)) {
|
||||
gtk_object_unref (GTK_OBJECT (stream));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream);
|
||||
CamelSeekableStream *seekable = (CamelSeekableStream *)stream;
|
||||
gint v;
|
||||
|
||||
g_assert (n);
|
||||
CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
|
||||
int nread;
|
||||
|
||||
if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
|
||||
n = MIN (seekable->bound_end - seekable->position, n);
|
||||
|
||||
do {
|
||||
v = read ( stream_fs->fd, buffer, n);
|
||||
} while (v == -1 && errno == EINTR);
|
||||
nread = read (stream_fs->fd, buffer, n);
|
||||
} while (nread == -1 && errno == EINTR);
|
||||
|
||||
if (v>0)
|
||||
seekable->position += v;
|
||||
|
||||
if (v == 0)
|
||||
if (nread > 0)
|
||||
seekable->position += nread;
|
||||
else if (nread == 0)
|
||||
stream->eos = TRUE;
|
||||
else {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not read from stream: %s",
|
||||
g_strerror (errno));
|
||||
}
|
||||
|
||||
return v;
|
||||
return nread;
|
||||
}
|
||||
|
||||
static gint
|
||||
stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
static int
|
||||
stream_write (CamelStream *stream, const char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream);
|
||||
CamelSeekableStream *seekable = (CamelSeekableStream *)stream;
|
||||
int v;
|
||||
gint written = 0;
|
||||
|
||||
g_assert (stream);
|
||||
g_assert (stream_fs->fd != -1);
|
||||
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
|
||||
int v, written = 0;
|
||||
|
||||
if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
|
||||
n = MIN (seekable->bound_end - seekable->position, n);
|
||||
|
||||
do {
|
||||
v = write ( stream_fs->fd, buffer, n);
|
||||
if (v>0)
|
||||
v = write (stream_fs->fd, buffer, n);
|
||||
if (v > 0)
|
||||
written += v;
|
||||
} while (v == -1 && errno == EINTR);
|
||||
|
||||
if (written>0)
|
||||
|
||||
if (written > 0)
|
||||
seekable->position += written;
|
||||
else if (v == -1) {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not write to stream: %s",
|
||||
g_strerror (errno));
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static void
|
||||
stream_flush (CamelStream *stream)
|
||||
stream_flush (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
fsync ((CAMEL_STREAM_FS (stream))->fd);
|
||||
if (fsync (CAMEL_STREAM_FS (stream)->fd) == -1) {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not flush stream data: %s",
|
||||
g_strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
static off_t
|
||||
stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy)
|
||||
stream_seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy, CamelException *ex)
|
||||
{
|
||||
CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream);
|
||||
off_t real = 0;
|
||||
@ -335,29 +316,34 @@ stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy po
|
||||
real = lseek(stream_fs->fd, offset, SEEK_END);
|
||||
if (real != -1)
|
||||
stream->position = real;
|
||||
else {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not seek to "
|
||||
"given offset: %s",
|
||||
g_strerror (errno));
|
||||
}
|
||||
return real;
|
||||
}
|
||||
real = stream->bound_end + offset;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stream->bound_end != CAMEL_STREAM_UNBOUND) {
|
||||
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)
|
||||
if (real == -1) {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not seek to given offset: %s",
|
||||
g_strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (real != stream->position && ((CamelStream *)stream)->eos)
|
||||
((CamelStream *)stream)->eos = FALSE;
|
||||
|
||||
stream->position = real;
|
||||
|
||||
|
||||
return real;
|
||||
}
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* camel-stream-fs.h :stream based on unix filesystem */
|
||||
|
||||
/*
|
||||
*
|
||||
* Author :
|
||||
/*
|
||||
* Author:
|
||||
* Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -50,26 +49,12 @@ struct _CamelStreamFs
|
||||
{
|
||||
CamelSeekableStream parent_object;
|
||||
|
||||
gchar *name; /* name of the underlying file */
|
||||
gint fd; /* file descriptor on the underlying file */
|
||||
int fd; /* file descriptor on the underlying file */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
CamelSeekableStreamClass parent_class;
|
||||
|
||||
/* Virtual methods */
|
||||
void (*init_with_fd) (CamelStreamFs *stream_fs,
|
||||
int fd);
|
||||
void (*init_with_fd_and_bounds) (CamelStreamFs *stream_fs,
|
||||
int fd, off_t start, off_t end);
|
||||
|
||||
int (*init_with_name) (CamelStreamFs *stream_fs,
|
||||
const gchar *name,
|
||||
int flags, int mode);
|
||||
int (*init_with_name_and_bounds) (CamelStreamFs *stream_fs,
|
||||
const gchar *name,
|
||||
int flags, int mode,
|
||||
off_t start, off_t end);
|
||||
} CamelStreamFsClass;
|
||||
|
||||
/* Standard Gtk function */
|
||||
@ -77,13 +62,20 @@ GtkType camel_stream_fs_get_type (void);
|
||||
|
||||
|
||||
/* public methods */
|
||||
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,
|
||||
int flags, int mode,
|
||||
off_t start, off_t end);
|
||||
CamelStream * camel_stream_fs_new_with_name (const char *name,
|
||||
int flags,
|
||||
mode_t mode,
|
||||
CamelException *ex);
|
||||
CamelStream * camel_stream_fs_new_with_name_and_bounds (const char *name,
|
||||
int flags, mode_t mode,
|
||||
off_t start,
|
||||
off_t end,
|
||||
CamelException *ex);
|
||||
|
||||
CamelStream * camel_stream_fs_new_with_fd (int fd);
|
||||
CamelStream * camel_stream_fs_new_with_fd_and_bounds (int fd, 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, off_t start,
|
||||
off_t end,
|
||||
CamelException *ex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
/* -*- 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 */
|
||||
|
||||
/*
|
||||
* Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
* Michael Zucchi <notzed@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -22,6 +22,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "camel-stream-mem.h"
|
||||
#include <sys/types.h>
|
||||
@ -31,43 +32,47 @@
|
||||
|
||||
static CamelStreamClass *parent_class = NULL;
|
||||
|
||||
/* Returns the class for a CamelStreamMEM */
|
||||
/* Returns the class for a CamelStreamMem */
|
||||
#define CSM_CLASS(so) CAMEL_STREAM_MEM_CLASS (GTK_OBJECT(so)->klass)
|
||||
|
||||
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 int stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex);
|
||||
static int stream_write (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
static gboolean stream_eos (CamelStream *stream);
|
||||
static off_t stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy);
|
||||
static off_t stream_seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy,
|
||||
CamelException *ex);
|
||||
|
||||
static void finalize (GtkObject *object);
|
||||
|
||||
static void
|
||||
camel_stream_mem_class_init (CamelStreamMemClass *camel_stream_mem_class)
|
||||
{
|
||||
CamelSeekableStreamClass *camel_seekable_stream_class = CAMEL_SEEKABLE_STREAM_CLASS (camel_stream_mem_class);
|
||||
CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_stream_mem_class);
|
||||
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_stream_mem_class);
|
||||
|
||||
CamelSeekableStreamClass *camel_seekable_stream_class =
|
||||
CAMEL_SEEKABLE_STREAM_CLASS (camel_stream_mem_class);
|
||||
CamelStreamClass *camel_stream_class =
|
||||
CAMEL_STREAM_CLASS (camel_stream_mem_class);
|
||||
GtkObjectClass *gtk_object_class =
|
||||
GTK_OBJECT_CLASS (camel_stream_mem_class);
|
||||
|
||||
parent_class = gtk_type_class (camel_stream_get_type ());
|
||||
|
||||
/* virtual method definition */
|
||||
|
||||
|
||||
/* virtual method overload */
|
||||
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_seekable_stream_class->seek = stream_seek;
|
||||
|
||||
|
||||
gtk_object_class->finalize = finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
camel_stream_mem_init (gpointer object, gpointer klass)
|
||||
camel_stream_mem_init (gpointer object, gpointer klass)
|
||||
{
|
||||
CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (object);
|
||||
|
||||
stream_mem->owner = FALSE;
|
||||
stream_mem->buffer = 0;
|
||||
}
|
||||
@ -76,9 +81,9 @@ GtkType
|
||||
camel_stream_mem_get_type (void)
|
||||
{
|
||||
static GtkType camel_stream_mem_type = 0;
|
||||
|
||||
if (!camel_stream_mem_type) {
|
||||
GtkTypeInfo camel_stream_mem_info =
|
||||
|
||||
if (!camel_stream_mem_type) {
|
||||
GtkTypeInfo camel_stream_mem_info =
|
||||
{
|
||||
"CamelStreamMem",
|
||||
sizeof (CamelStreamMem),
|
||||
@ -89,10 +94,10 @@ camel_stream_mem_get_type (void)
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
|
||||
camel_stream_mem_type = gtk_type_unique (camel_seekable_stream_get_type (), &camel_stream_mem_info);
|
||||
}
|
||||
|
||||
|
||||
return camel_stream_mem_type;
|
||||
}
|
||||
|
||||
@ -117,11 +122,11 @@ CamelStream *
|
||||
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->buffer = byte_array;
|
||||
stream_mem->owner = TRUE;
|
||||
|
||||
|
||||
return CAMEL_STREAM (stream_mem);
|
||||
}
|
||||
|
||||
@ -134,7 +139,8 @@ void camel_stream_mem_set_byte_array (CamelStreamMem *s, GByteArray *buffer)
|
||||
s->buffer = buffer;
|
||||
}
|
||||
|
||||
void camel_stream_mem_set_buffer (CamelStreamMem *s, const char *buffer, size_t len)
|
||||
void camel_stream_mem_set_buffer (CamelStreamMem *s, const char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
GByteArray *ba;
|
||||
|
||||
@ -143,7 +149,7 @@ void camel_stream_mem_set_buffer (CamelStreamMem *s, const char *buffer, size_t
|
||||
camel_stream_mem_set_byte_array(s, ba);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
finalize (GtkObject *object)
|
||||
{
|
||||
CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (object);
|
||||
@ -154,71 +160,68 @@ finalize (GtkObject *object)
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint
|
||||
stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
static int
|
||||
stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (stream);
|
||||
CamelSeekableStream *seekable = (CamelSeekableStream *)stream;
|
||||
CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
|
||||
|
||||
g_assert (stream);
|
||||
|
||||
if (seekable->bound_end != CAMEL_STREAM_UNBOUND) {
|
||||
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);
|
||||
if (n > 0) {
|
||||
memcpy (buffer, camel_stream_mem->buffer->data +
|
||||
seekable->position, n);
|
||||
seekable->position += n;
|
||||
} else {
|
||||
} else
|
||||
n = -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static gint
|
||||
stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
static int
|
||||
stream_write (CamelStream *stream, const char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream);
|
||||
CamelSeekableStream *seekable = (CamelSeekableStream *)stream;
|
||||
CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
|
||||
|
||||
g_assert (stream);
|
||||
|
||||
if (seekable->bound_end != CAMEL_STREAM_UNBOUND) {
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
stream_flush (CamelStream *stream)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
return;
|
||||
return n;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stream_eos (CamelStream *stream)
|
||||
{
|
||||
return ((CamelStreamMem *)stream)->buffer->len <= ((CamelSeekableStream *)stream)->position;
|
||||
CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream);
|
||||
CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);
|
||||
|
||||
return stream_mem->buffer->len <= seekable_stream->position;
|
||||
}
|
||||
|
||||
static off_t
|
||||
stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy)
|
||||
stream_seek (CamelSeekableStream *stream, off_t offset,
|
||||
CamelStreamSeekPolicy policy, CamelException *ex)
|
||||
{
|
||||
off_t position;
|
||||
CamelStreamMem *stream_mem = (CamelStreamMem *)stream;
|
||||
CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream);
|
||||
|
||||
switch (policy) {
|
||||
case CAMEL_STREAM_SET:
|
||||
@ -230,24 +233,20 @@ stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy po
|
||||
case CAMEL_STREAM_END:
|
||||
position = (stream_mem->buffer)->len + offset;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stream->bound_end == CAMEL_STREAM_UNBOUND) {
|
||||
if (stream->bound_end == CAMEL_STREAM_UNBOUND)
|
||||
position = MIN (position, stream->bound_end);
|
||||
}
|
||||
if (stream->bound_start == CAMEL_STREAM_UNBOUND) {
|
||||
if (stream->bound_start == CAMEL_STREAM_UNBOUND)
|
||||
position = MAX (position, 0);
|
||||
} else {
|
||||
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);
|
||||
g_byte_array_set_size (stream_mem->buffer, position);
|
||||
memset (stream_mem->buffer->data + oldlen, 0,
|
||||
position - oldlen);
|
||||
}
|
||||
|
||||
stream->position = position;
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
/* -*- 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 */
|
||||
|
||||
/*
|
||||
* Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
* Michael Zucchi <notzed@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -50,8 +51,8 @@ struct _CamelStreamMem
|
||||
|
||||
typedef struct {
|
||||
CamelSeekableStreamClass parent_class;
|
||||
|
||||
/* Virtual methods */
|
||||
|
||||
/* Virtual methods */
|
||||
} CamelStreamMemClass;
|
||||
|
||||
/* Standard Gtk function */
|
||||
@ -64,7 +65,8 @@ 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);
|
||||
void camel_stream_mem_set_buffer (CamelStreamMem *, const char *buffer,
|
||||
size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* camel-stream.c : abstract class for a stream */
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Author :
|
||||
/*
|
||||
* Author:
|
||||
* Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -24,71 +22,36 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "camel-stream.h"
|
||||
|
||||
|
||||
enum {
|
||||
DATA_AVAILABLE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint camel_stream_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static CamelObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
/* Returns the class for a CamelStream */
|
||||
#define CS_CLASS(so) CAMEL_STREAM_CLASS (GTK_OBJECT(so)->klass)
|
||||
|
||||
static void
|
||||
default_camel_flush (CamelStream *stream)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eos (CamelStream *stream)
|
||||
{
|
||||
return stream->eos;
|
||||
}
|
||||
static void stream_flush (CamelStream *stream, CamelException *ex);
|
||||
static gboolean stream_eos (CamelStream *stream);
|
||||
|
||||
|
||||
static void
|
||||
camel_stream_class_init (CamelStreamClass *camel_stream_class)
|
||||
{
|
||||
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_stream_class);
|
||||
|
||||
parent_class = gtk_type_class (camel_object_get_type ());
|
||||
|
||||
/* virtual method definition */
|
||||
camel_stream_class->read = NULL;
|
||||
camel_stream_class->write = NULL;
|
||||
camel_stream_class->flush = default_camel_flush;
|
||||
camel_stream_class->eos = eos;
|
||||
|
||||
/* virtual method overload */
|
||||
|
||||
/* signal definition */
|
||||
camel_stream_signals[DATA_AVAILABLE] =
|
||||
gtk_signal_new ("data_available",
|
||||
GTK_RUN_LAST,
|
||||
gtk_object_class->type,
|
||||
GTK_SIGNAL_OFFSET (CamelStreamClass, data_available),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
gtk_object_class_add_signals (gtk_object_class, camel_stream_signals, LAST_SIGNAL);
|
||||
|
||||
camel_stream_class->flush = stream_flush;
|
||||
camel_stream_class->eos = stream_eos;
|
||||
}
|
||||
|
||||
GtkType
|
||||
camel_stream_get_type (void)
|
||||
{
|
||||
static GtkType camel_stream_type = 0;
|
||||
|
||||
|
||||
if (!camel_stream_type) {
|
||||
GtkTypeInfo camel_stream_info =
|
||||
GtkTypeInfo camel_stream_info =
|
||||
{
|
||||
"CamelStream",
|
||||
sizeof (CamelStream),
|
||||
@ -99,71 +62,103 @@ camel_stream_get_type (void)
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
camel_stream_type = gtk_type_unique (camel_object_get_type (), &camel_stream_info);
|
||||
|
||||
camel_stream_type = gtk_type_unique (camel_object_get_type (),
|
||||
&camel_stream_info);
|
||||
}
|
||||
|
||||
|
||||
return camel_stream_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_stream_read:
|
||||
* camel_stream_read:
|
||||
* @stream: a CamelStream.
|
||||
* @buffer: buffer where bytes pulled from the stream are stored.
|
||||
* @n: max number of bytes to read.
|
||||
*
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Read at most @n bytes from the @stream object and stores them
|
||||
* in the buffer pointed at by @buffer.
|
||||
*
|
||||
* Return value: number of bytes actually read.
|
||||
*
|
||||
* Return value: number of bytes actually read. If an error occurs,
|
||||
* @ex will contain a description of the error.
|
||||
**/
|
||||
gint
|
||||
camel_stream_read (CamelStream *stream, gchar *buffer, gint n)
|
||||
int
|
||||
camel_stream_read (CamelStream *stream, char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
return CS_CLASS (stream)->read (stream, buffer, n);
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
|
||||
g_return_val_if_fail (n == 0 || buffer, -1);
|
||||
|
||||
return CS_CLASS (stream)->read (stream, buffer, n, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_stream_write:
|
||||
* camel_stream_write:
|
||||
* @stream: a CamelStream object.
|
||||
* @buffer: buffer to write.
|
||||
* @n: number of bytes to write
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Write @n bytes from the buffer pointed at by @buffer into @stream.
|
||||
*
|
||||
* Return value: the number of bytes actually written
|
||||
* in the stream.
|
||||
* Return value: the number of bytes actually written to the stream. If
|
||||
* an error occurs, @ex will contain a description of the error.
|
||||
**/
|
||||
gint
|
||||
camel_stream_write (CamelStream *stream, const gchar *buffer, gint n)
|
||||
int
|
||||
camel_stream_write (CamelStream *stream, const char *buffer, unsigned int n,
|
||||
CamelException *ex)
|
||||
{
|
||||
return CS_CLASS (stream)->write (stream, buffer, n);
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
|
||||
g_return_val_if_fail (n == 0 || buffer, -1);
|
||||
|
||||
return CS_CLASS (stream)->write (stream, buffer, n, ex);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stream_flush (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_stream_flush:
|
||||
* @stream: a CamelStream object
|
||||
*
|
||||
* Flushes the contents of the stream to its backing store.
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Flushes the contents of the stream to its backing store. Only meaningful
|
||||
* on writable streams. If an error occurs, @ex will be set.
|
||||
**/
|
||||
void
|
||||
camel_stream_flush (CamelStream *stream)
|
||||
camel_stream_flush (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
CS_CLASS (stream)->flush (stream);
|
||||
g_return_if_fail (CAMEL_IS_STREAM (stream));
|
||||
|
||||
CS_CLASS (stream)->flush (stream, ex);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
stream_eos (CamelStream *stream)
|
||||
{
|
||||
return stream->eos;
|
||||
}
|
||||
|
||||
/**
|
||||
* camel_stream_eos:
|
||||
* camel_stream_eos:
|
||||
* @stream: a CamelStream object
|
||||
*
|
||||
*
|
||||
* Test if there are bytes left to read on the @stream object.
|
||||
*
|
||||
*
|
||||
* Return value: %TRUE if all the contents on the stream has been read, or
|
||||
* %FALSE if information is still available.
|
||||
**/
|
||||
gboolean
|
||||
camel_stream_eos (CamelStream *stream)
|
||||
{
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (stream), TRUE);
|
||||
|
||||
return CS_CLASS (stream)->eos (stream);
|
||||
}
|
||||
|
||||
@ -171,67 +166,69 @@ camel_stream_eos (CamelStream *stream)
|
||||
/**
|
||||
* camel_stream_reset: reset a stream
|
||||
* @stream: the stream object
|
||||
*
|
||||
* Reset a stream, that is put it in a state
|
||||
* where it can be read from the begining.
|
||||
* All streams in camel are not seekable,
|
||||
* but they must all be resettable.
|
||||
*
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* Reset a stream. That is, put it in a state where it can be read
|
||||
* from the beginning again. Not all streams in Camel are seekable,
|
||||
* but they must all be resettable.
|
||||
**/
|
||||
void
|
||||
camel_stream_reset (CamelStream *stream)
|
||||
{
|
||||
CS_CLASS (stream)->reset (stream);
|
||||
void
|
||||
camel_stream_reset (CamelStream *stream, CamelException *ex)
|
||||
{
|
||||
g_return_if_fail (CAMEL_IS_STREAM (stream));
|
||||
|
||||
CS_CLASS (stream)->reset (stream, ex);
|
||||
}
|
||||
|
||||
/***************** Utility functions ********************/
|
||||
|
||||
/**
|
||||
* came_stream_write_strings:
|
||||
* @stream: a CamelStream object.
|
||||
* @...: A %NULL terminated list of strings.
|
||||
* camel_stream_write_string:
|
||||
* @stream: a stream object
|
||||
* @string: a string
|
||||
* @ex: a CamelException
|
||||
*
|
||||
* This is a utility function that writes the list of
|
||||
* strings into the @stream object.
|
||||
* Writes the string to the stream.
|
||||
*
|
||||
* Returns number of successfully written bytes.
|
||||
*/
|
||||
* Return value: the number of characters output.
|
||||
**/
|
||||
int
|
||||
camel_stream_write_strings (CamelStream *stream, ... )
|
||||
camel_stream_write_string (CamelStream *stream, const char *string,
|
||||
CamelException *ex)
|
||||
{
|
||||
va_list args;
|
||||
const char *string;
|
||||
int total = 0;
|
||||
|
||||
va_start(args, stream);
|
||||
string = va_arg (args, const char *);
|
||||
|
||||
while (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;
|
||||
return camel_stream_write (stream, string, strlen (string), ex);
|
||||
}
|
||||
|
||||
int camel_stream_printf (CamelStream *stream, const char *fmt, ... )
|
||||
/**
|
||||
* camel_stream_printf:
|
||||
* @stream: a stream object
|
||||
* @ex: a CamelException
|
||||
* @fmt: a printf-style format string
|
||||
*
|
||||
* This printfs the given data to @stream. If an error occurs, @ex
|
||||
* will be set.
|
||||
*
|
||||
* Return value: the number of characters output.
|
||||
**/
|
||||
int
|
||||
camel_stream_printf (CamelStream *stream, CamelException *ex,
|
||||
const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
char *string;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
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);
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
|
||||
|
||||
va_start (args, fmt);
|
||||
string = g_strdup_vprintf (fmt, args);
|
||||
va_end (args);
|
||||
|
||||
if (!string)
|
||||
return -1;
|
||||
|
||||
ret = camel_stream_write (stream, string, strlen (string), ex);
|
||||
g_free (string);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -239,40 +236,37 @@ int camel_stream_printf (CamelStream *stream, const char *fmt, ... )
|
||||
* camel_stream_write_to_stream:
|
||||
* @stream: Source CamelStream.
|
||||
* @output_stream: Destination CamelStream.
|
||||
*
|
||||
* @ex: a CamelException.
|
||||
*
|
||||
* Write all of a stream (until eos) into another stream, in a blocking
|
||||
* fashion.
|
||||
*
|
||||
* Return Value: Returns -1 on error, or the number of bytes succesfully
|
||||
* Return value: Returns -1 on error, or the number of bytes succesfully
|
||||
* copied across streams.
|
||||
**/
|
||||
int
|
||||
camel_stream_write_to_stream (CamelStream *stream,
|
||||
CamelStream *output_stream)
|
||||
camel_stream_write_to_stream (CamelStream *stream, CamelStream *output_stream,
|
||||
CamelException *ex)
|
||||
{
|
||||
gchar tmp_buf[4096];
|
||||
char tmp_buf[4096];
|
||||
int total = 0;
|
||||
gint nb_read;
|
||||
gint nb_written;
|
||||
int nb_read;
|
||||
int nb_written;
|
||||
|
||||
/*
|
||||
* default implementation that uses the input
|
||||
* stream and stream it in a blocking way
|
||||
* to an output stream.
|
||||
*/
|
||||
g_assert (output_stream);
|
||||
g_assert (stream);
|
||||
|
||||
while (!camel_stream_eos (CAMEL_STREAM (stream))) {
|
||||
nb_read = camel_stream_read (CAMEL_STREAM (stream), tmp_buf, 4096);
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
|
||||
g_return_val_if_fail (CAMEL_IS_STREAM (output_stream), -1);
|
||||
|
||||
while (!camel_stream_eos (stream)) {
|
||||
nb_read = camel_stream_read (stream, tmp_buf,
|
||||
sizeof (tmp_buf), ex);
|
||||
if (nb_read < 0)
|
||||
return -1;
|
||||
else if (nb_read>0) {
|
||||
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);
|
||||
if (len<0)
|
||||
int len = camel_stream_write (output_stream, tmp_buf + nb_written, nb_read - nb_written, ex);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
nb_written += len;
|
||||
}
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* camel-stream.h : class for an abstract stream */
|
||||
|
||||
/*
|
||||
*
|
||||
* Author :
|
||||
/*
|
||||
* Author:
|
||||
* Bertrand Guiheneuf <bertrand@helixcode.com>
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
@ -35,6 +34,7 @@ extern "C" {
|
||||
#endif /* __cplusplus }*/
|
||||
|
||||
#include <camel/camel-object.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define CAMEL_STREAM_TYPE (camel_stream_get_type ())
|
||||
#define CAMEL_STREAM(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_TYPE, CamelStream))
|
||||
@ -45,49 +45,53 @@ struct _CamelStream
|
||||
{
|
||||
CamelObject parent_object;
|
||||
|
||||
gboolean eos; /* end of stream indicator, for use by implementing classes */
|
||||
gboolean eos;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
CamelObjectClass parent_class;
|
||||
|
||||
/* Virtual methods */
|
||||
|
||||
void (*data_available) (CamelStream *stream); /* default "data_available" signal handler */
|
||||
|
||||
gint (*read) (CamelStream *stream, gchar *buffer, gint n);
|
||||
gint (*write) (CamelStream *stream, const gchar *buffer, gint n);
|
||||
void (*flush) (CamelStream *stream);
|
||||
/* Virtual methods */
|
||||
|
||||
int (*read) (CamelStream *stream, char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
int (*write) (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
void (*flush) (CamelStream *stream, CamelException *ex);
|
||||
gboolean (*eos) (CamelStream *stream);
|
||||
void (*reset) (CamelStream *stream);
|
||||
void (*reset) (CamelStream *stream, CamelException *ex);
|
||||
|
||||
} 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_eos (CamelStream *stream);
|
||||
void camel_stream_reset (CamelStream *stream);
|
||||
int camel_stream_read (CamelStream *stream, char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
int camel_stream_write (CamelStream *stream, const char *buffer,
|
||||
unsigned int n, CamelException *ex);
|
||||
void camel_stream_flush (CamelStream *stream, CamelException *ex);
|
||||
gboolean camel_stream_eos (CamelStream *stream);
|
||||
void camel_stream_reset (CamelStream *stream, CamelException *ex);
|
||||
|
||||
/* utility macros and funcs */
|
||||
#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);
|
||||
int camel_stream_write_string (CamelStream *stream, const char *string,
|
||||
CamelException *ex);
|
||||
int camel_stream_printf (CamelStream *stream, CamelException *ex,
|
||||
const char *fmt, ... ) G_GNUC_PRINTF (3, 4);
|
||||
int camel_stream_vprintf (CamelStream *stream, CamelException *ex,
|
||||
const char *fmt, va_list ap);
|
||||
|
||||
/* 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);
|
||||
/* 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,
|
||||
CamelException *ex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CAMEL_STREAM_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -130,7 +130,8 @@ gmime_content_field_write_to_stream (GMimeContentField *content_field, CamelStre
|
||||
|
||||
txt = header_content_type_format(content_field->content_type);
|
||||
if (txt) {
|
||||
camel_stream_write_strings (stream, "Content-Type: ", txt, "\n", NULL);
|
||||
/* FIXME. Shouldn't pass NULL for CamelException. */
|
||||
camel_stream_printf (stream, NULL, "Content-Type: %s\n", txt);
|
||||
g_free(txt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,10 +335,11 @@ md5_get_digest_from_stream (CamelStream *stream, guchar digest[16])
|
||||
|
||||
md5_init (&ctx);
|
||||
|
||||
nb_bytes_read = camel_stream_read (stream, tmp_buf, 1024);
|
||||
/* FIXME (the NULL) */
|
||||
nb_bytes_read = camel_stream_read (stream, tmp_buf, 1024, NULL);
|
||||
while (nb_bytes_read) {
|
||||
md5_update (&ctx, tmp_buf, nb_bytes_read);
|
||||
nb_bytes_read = camel_stream_read (stream, tmp_buf, 1024);
|
||||
nb_bytes_read = camel_stream_read (stream, tmp_buf, 1024, NULL);
|
||||
}
|
||||
|
||||
md5_final (&ctx, digest);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = mbox pop3 sendmail smtp
|
||||
SUBDIRS = mbox pop3 sendmail
|
||||
|
||||
# these ones are disabled for the moment.
|
||||
# MH maildir imap smtp
|
||||
# MH maildir nntp smtp
|
||||
|
||||
@ -721,11 +721,11 @@ mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept
|
||||
if (stat(mbox_folder->folder_file_path, &st) != 0)
|
||||
goto fail;
|
||||
|
||||
output_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, O_RDWR, 0600);
|
||||
output_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, O_RDWR, 0600, ex);
|
||||
if (output_stream == NULL)
|
||||
goto fail;
|
||||
|
||||
seek = camel_seekable_stream_seek((CamelSeekableStream *)output_stream, st.st_size, SEEK_SET);
|
||||
seek = camel_seekable_stream_seek((CamelSeekableStream *)output_stream, st.st_size, SEEK_SET, ex);
|
||||
if (seek != st.st_size)
|
||||
goto fail;
|
||||
|
||||
@ -737,23 +737,21 @@ mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept
|
||||
g_free(xev);
|
||||
|
||||
/* we must write this to the non-filtered stream ... */
|
||||
if (camel_stream_write_string (output_stream, "From - \n") == -1)
|
||||
if (camel_stream_write_string (output_stream, "From - \n", ex) == -1)
|
||||
goto fail;
|
||||
|
||||
/* and write the content to the filtering stream, that translated '\nFrom' into '\n>From' */
|
||||
filter_stream = (CamelStream *)camel_stream_filter_new_with_stream(output_stream);
|
||||
filter_from = (CamelMimeFilter *)camel_mime_filter_from_new();
|
||||
camel_stream_filter_add((CamelStreamFilter *)filter_stream, filter_from);
|
||||
if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), filter_stream) == -1)
|
||||
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message),
|
||||
filter_stream, ex);
|
||||
if (!camel_exception_is_set (ex))
|
||||
camel_stream_flush (filter_stream, ex);
|
||||
|
||||
if (camel_exception_is_set (ex))
|
||||
goto fail;
|
||||
|
||||
#warning WE NEED A STREAM CLOSE OR THIS WILL FAIL TO WORK
|
||||
#warning WE NEED A STREAM CLOSE OR THIS WILL FAIL TO WORK
|
||||
#warning WE NEED A STREAM CLOSE OR THIS WILL FAIL TO WORK
|
||||
#warning WE NEED A STREAM CLOSE OR THIS WILL FAIL TO WORK
|
||||
|
||||
/* FIXME: stream_close doesn't return anything */
|
||||
/* camel_stream_close (filter_stream);*/
|
||||
gtk_object_unref (GTK_OBJECT (filter_stream));
|
||||
|
||||
/* force a summary update - will only update from the new position, if it can */
|
||||
@ -761,9 +759,15 @@ mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept
|
||||
return;
|
||||
|
||||
fail:
|
||||
camel_exception_setv (ex,
|
||||
CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */
|
||||
"Cannot append to mbox file: %s", strerror (errno));
|
||||
if (camel_exception_is_set (ex)) {
|
||||
camel_exception_setv (ex, camel_exception_get_id (ex),
|
||||
"Cannot append message to mbox file: %s",
|
||||
camel_exception_get_description (ex));
|
||||
} else {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot append message to mbox file: %s",
|
||||
g_strerror (errno));
|
||||
}
|
||||
if (filter_stream) {
|
||||
/*camel_stream_close (filter_stream);*/
|
||||
gtk_object_unref ((GtkObject *)filter_stream);
|
||||
@ -861,7 +865,7 @@ mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
|
||||
g_assert(info->frompos != -1);
|
||||
|
||||
/* where we read from */
|
||||
message_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, O_RDONLY, 0);
|
||||
message_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, O_RDONLY, 0, ex);
|
||||
if (message_stream == NULL)
|
||||
goto fail;
|
||||
|
||||
@ -900,9 +904,15 @@ mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
|
||||
return message;
|
||||
|
||||
fail:
|
||||
camel_exception_setv (ex,
|
||||
CAMEL_EXCEPTION_FOLDER_INVALID_UID,
|
||||
"Cannot get message: %s", strerror(errno));
|
||||
if (camel_exception_is_set (ex)) {
|
||||
camel_exception_setv (ex, camel_exception_get_id (ex),
|
||||
"Cannot get message: %s",
|
||||
camel_exception_get_description (ex));
|
||||
} else {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
|
||||
"Cannot get message: %s",
|
||||
g_strerror(errno));
|
||||
}
|
||||
if (parser)
|
||||
gtk_object_unref((GtkObject *)parser);
|
||||
if (message_stream)
|
||||
|
||||
@ -196,12 +196,13 @@ get_message_by_number (CamelFolder *folder, gint number, CamelException *ex)
|
||||
}
|
||||
g_free (result);
|
||||
|
||||
body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store));
|
||||
body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store), ex);
|
||||
if (!body) {
|
||||
CamelService *service = CAMEL_SERVICE (folder->parent_store);
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
|
||||
"Could not retrieve message from POP "
|
||||
"server %s.", service->url->host);
|
||||
"server %s: %s", service->url->host,
|
||||
camel_exception_get_description (ex));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -376,14 +376,15 @@ pop3_connect (CamelService *service, CamelException *ex)
|
||||
CAMEL_STREAM_BUFFER_READ);
|
||||
|
||||
/* Read the greeting, note APOP timestamp, if any. */
|
||||
buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream));
|
||||
buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream), ex);
|
||||
if (!buf) {
|
||||
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
|
||||
"Could not read greeting from POP "
|
||||
"server.");
|
||||
return FALSE;
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
|
||||
"Could not read greeting from POP "
|
||||
"server: %s",
|
||||
camel_exception_get_description (ex));
|
||||
gtk_object_unref (GTK_OBJECT (store->ostream));
|
||||
gtk_object_unref (GTK_OBJECT (store->istream));
|
||||
return FALSE;
|
||||
}
|
||||
apoptime = strchr (buf, '<');
|
||||
apopend = apoptime ? strchr (apoptime, '>') : NULL;
|
||||
@ -512,18 +513,30 @@ camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...)
|
||||
char *cmdbuf, *respbuf;
|
||||
va_list ap;
|
||||
int status;
|
||||
CamelException *ex = camel_exception_new ();
|
||||
|
||||
va_start (ap, fmt);
|
||||
cmdbuf = g_strdup_vprintf (fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* Send the command */
|
||||
camel_stream_write (store->ostream, cmdbuf, strlen (cmdbuf));
|
||||
camel_stream_printf (store->ostream, ex, "%s\r\n", cmdbuf);
|
||||
g_free (cmdbuf);
|
||||
camel_stream_write (store->ostream, "\r\n", 2);
|
||||
if (camel_exception_is_set (ex)) {
|
||||
if (*ret)
|
||||
*ret = g_strdup (camel_exception_get_description (ex));
|
||||
camel_exception_free (ex);
|
||||
return CAMEL_POP3_FAIL;
|
||||
}
|
||||
|
||||
/* Read the response */
|
||||
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream));
|
||||
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream), ex);
|
||||
if (camel_exception_is_set (ex)) {
|
||||
if (*ret)
|
||||
*ret = g_strdup (camel_exception_get_description (ex));
|
||||
camel_exception_free (ex);
|
||||
return CAMEL_POP3_FAIL;
|
||||
}
|
||||
if (!strncmp (respbuf, "+OK", 3))
|
||||
status = CAMEL_POP3_OK;
|
||||
else if (!strncmp (respbuf, "-ERR", 4))
|
||||
@ -559,7 +572,8 @@ camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...)
|
||||
* Return value: the data, which the caller must free.
|
||||
**/
|
||||
char *
|
||||
camel_pop3_command_get_additional_data (CamelPop3Store *store)
|
||||
camel_pop3_command_get_additional_data (CamelPop3Store *store,
|
||||
CamelException *ex)
|
||||
{
|
||||
CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream);
|
||||
GPtrArray *data;
|
||||
@ -568,7 +582,7 @@ camel_pop3_command_get_additional_data (CamelPop3Store *store)
|
||||
|
||||
data = g_ptr_array_new ();
|
||||
while (1) {
|
||||
buf = camel_stream_buffer_read_line (stream);
|
||||
buf = camel_stream_buffer_read_line (stream, ex);
|
||||
if (!buf) {
|
||||
status = CAMEL_POP3_FAIL;
|
||||
break;
|
||||
|
||||
@ -66,7 +66,8 @@ void camel_pop3_store_close (CamelPop3Store *store, gboolean expunge,
|
||||
/* support functions */
|
||||
enum { CAMEL_POP3_OK, CAMEL_POP3_ERR, CAMEL_POP3_FAIL };
|
||||
int camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...);
|
||||
char *camel_pop3_command_get_additional_data (CamelPop3Store *store);
|
||||
char *camel_pop3_command_get_additional_data (CamelPop3Store *store,
|
||||
CamelException *ex);
|
||||
|
||||
/* Standard Gtk function */
|
||||
GtkType camel_pop3_store_get_type (void);
|
||||
|
||||
@ -139,9 +139,17 @@ _send_internal (CamelMedium *message, char **argv, CamelException *ex)
|
||||
/* Parent process. Write the message out. */
|
||||
close (fd[0]);
|
||||
out = camel_stream_fs_new_with_fd (fd[1]);
|
||||
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), out);
|
||||
camel_stream_flush (out);
|
||||
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message),
|
||||
out, ex);
|
||||
if (!camel_exception_is_set (ex))
|
||||
camel_stream_flush (out, ex);
|
||||
gtk_object_unref (GTK_OBJECT (out));
|
||||
if (camel_exception_is_set (ex)) {
|
||||
camel_exception_setv (ex, camel_exception_get_id (ex),
|
||||
"Could not send message: %s",
|
||||
camel_exception_get_description (ex));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Wait for sendmail to exit. */
|
||||
while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
|
||||
|
||||
Reference in New Issue
Block a user