diff options
author | NotZed <NotZed@HelixCode.com> | 2000-04-21 07:48:45 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2000-04-21 07:48:45 +0800 |
commit | 383f245d39b8b806a4b6ce4dea7b0ab7f1658450 (patch) | |
tree | b6447bbcd6bd8c4b31582a343ce062e8d2c548c4 /camel/camel-stream-filter.c | |
parent | 6b5b1f6de926a4c9dec95dbd55ae53a5b30fb6a5 (diff) | |
download | gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.gz gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.zst gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.zip |
MERGE NEW_PARSER branch into HEAD, fixed conflicts.
2000-04-20 NotZed <NotZed@HelixCode.com>
* MERGE NEW_PARSER branch into HEAD, fixed conflicts.
* gmime-content-field.c (_print_parameter): Duh, removed again
(@@#$@ cvs merge).
* camel-mime-utils.c (header_content_type_is): Constify.
(header_content_type_unref): Killed a couple warnings.
* camel-folder.c (_init): Removed more log crap.
* providers/Makefile.am (SUBDIRS): Removed nntp, pending fixes for
summary changes.
* providers/mbox/camel-mbox-folder.c (_get_message_by_number):
Fixed for new summary interface. Added a warning for using this
broken api.
(_get_message_by_uid): Fixed for message new with session
vanishing.
svn path=/trunk/; revision=2531
Diffstat (limited to 'camel/camel-stream-filter.c')
-rw-r--r-- | camel/camel-stream-filter.c | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/camel/camel-stream-filter.c b/camel/camel-stream-filter.c new file mode 100644 index 0000000000..9d6c7d11b0 --- /dev/null +++ b/camel/camel-stream-filter.c @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2000 Helix Code Inc. + * + * Authors: Michael Zucchi <notzed@helixcode.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "camel-stream-filter.h" + +struct _filter { + struct _filter *next; + int id; + CamelMimeFilter *filter; +}; + +struct _CamelStreamFilterPrivate { + struct _filter *filters; + int filterid; /* next filter id */ + + char *realbuffer; /* buffer - READ_PAD */ + char *buffer; /* READ_SIZE bytes */ + + char *filtered; /* the filtered data */ + size_t filteredlen; +}; + +#define READ_PAD (64) /* bytes padded before buffer */ +#define READ_SIZE (4096) + +#define _PRIVATE(o) (((CamelStreamFilter *)(o))->priv) + +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 gboolean do_available (CamelStream *stream); +static gboolean do_eos (CamelStream *stream); +static void do_close (CamelStream *stream); +static void do_reset (CamelStream *stream); + +static CamelStreamClass *camel_stream_filter_parent; + +enum SIGNALS { + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +guint +camel_stream_filter_get_type (void) +{ + static guint type = 0; + + if (!type) { + GtkTypeInfo type_info = { + "CamelStreamFilter", + sizeof (CamelStreamFilter), + sizeof (CamelStreamFilterClass), + (GtkClassInitFunc) camel_stream_filter_class_init, + (GtkObjectInitFunc) camel_stream_filter_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + type = gtk_type_unique (camel_stream_get_type (), &type_info); + } + + return type; +} + +static void +finalise(GtkObject *o) +{ + CamelStreamFilter *filter = (CamelStreamFilter *)o; + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + struct _filter *fn, *f; + + f = p->filters; + while (f) { + fn = f->next; + gtk_object_unref((GtkObject *)f->filter); + g_free(f); + f = fn; + } + g_free(p->realbuffer); + g_free(p); +} + + +static void +camel_stream_filter_class_init (CamelStreamFilterClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + CamelStreamClass *camel_stream_class = (CamelStreamClass *) klass; + + camel_stream_filter_parent = gtk_type_class (camel_stream_get_type ()); + + object_class->finalize = finalise; + + camel_stream_class->read = do_read; + camel_stream_class->write = do_write; + camel_stream_class->flush = do_flush; + camel_stream_class->available = do_available; + camel_stream_class->eos = do_eos; + camel_stream_class->close = do_close; + camel_stream_class->reset = do_reset; + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} + +static void +camel_stream_filter_init (CamelStreamFilter *obj) +{ + struct _CamelStreamFilterPrivate *p; + + _PRIVATE(obj) = p = g_malloc0(sizeof(*p)); + p->realbuffer = g_malloc(READ_SIZE + READ_PAD); + p->buffer = p->realbuffer + READ_PAD; +} + +/** + * camel_stream_filter_new: + * + * Create a new CamelStreamFilter object. + * + * Return value: A new CamelStreamFilter object. + **/ +CamelStreamFilter * +camel_stream_filter_new_with_stream(CamelStream *stream) +{ + CamelStreamFilter *new = CAMEL_STREAM_FILTER ( gtk_type_new (camel_stream_filter_get_type ())); + + new->source = stream; + return new; +} + + +/** + * camel_stream_filter_add: + * @filter: Initialised CamelStreamFilter. + * @mf: Filter to perform processing on stream. + * + * Add a new CamelMimeFilter to execute during the processing of this + * stream. Each filter added is processed after the previous one. + * + * Note that a filter should only be added to a single stream + * at a time, otherwise unpredictable results may occur. + * + * Return value: A filter id for this CamelStreamFilter. + **/ +int +camel_stream_filter_add(CamelStreamFilter *filter, CamelMimeFilter *mf) +{ + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + struct _filter *fn, *f; + + fn = g_malloc(sizeof(*fn)); + fn->id = p->filterid++; + fn->filter = mf; + gtk_object_ref((GtkObject *)mf); + + /* sure, we could use a GList, but we wouldn't save much */ + f = (struct _filter *)&p->filters; + while (f->next) + f = f->next; + f->next = fn; + fn->next = NULL; + return fn->id; +} + +/** + * camel_stream_filter_remove: + * @filter: Initialised CamelStreamFilter. + * @id: Filter id, as returned from camel_stream_filter_add(). + * + * Remove a processing filter from the stream, by id. + **/ +void +camel_stream_filter_remove(CamelStreamFilter *filter, int id) +{ + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + struct _filter *fn, *f; + + f = (struct _filter *)&p->filters; + while (f && f->next) { + fn = f->next; + if (fn->id == id) { + f->next = fn->next; + gtk_object_unref((GtkObject *)fn->filter); + g_free(fn); + } + f = f->next; + } +} + +static gint do_read (CamelStream *stream, gchar *buffer, gint n) +{ + CamelStreamFilter *filter = (CamelStreamFilter *)stream; + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + int size; + struct _filter *f; + + if (p->filteredlen<=0) { + int presize = READ_SIZE; + + size = camel_stream_read(filter->source, p->buffer, READ_SIZE); + if (size<=0) { + /* this is somewhat untested */ + if (camel_stream_eos(filter->source)) { + f = p->filters; + p->filtered = p->buffer; + p->filteredlen = 0; + while (f) { + camel_mime_filter_complete(f->filter, p->filtered, p->filteredlen, presize, &p->filtered, &p->filteredlen, &presize); + f = f->next; + } + size = p->filteredlen; + } + if (size<=0) + return size; + } else { + f = p->filters; + p->filtered = p->buffer; + p->filteredlen = size; + while (f) { + camel_mime_filter_filter(f->filter, p->filtered, p->filteredlen, presize, &p->filtered, &p->filteredlen, &presize); + f = f->next; + } + } + } + + size = MIN(n, p->filteredlen); + memcpy(buffer, p->filtered, size); + p->filteredlen -= size; + p->filtered += size; + + return size; +} + +static gint do_write (CamelStream *stream, const gchar *buffer, gint n) +{ + /* what semantics *should* this have?? */ + g_warning("Writing to a non-writable stream"); + return -1; +} + +static void do_flush (CamelStream *stream) +{ + /* NO OP */ +} + +static gboolean do_available (CamelStream *stream) +{ + CamelStreamFilter *filter = (CamelStreamFilter *)stream; + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + + if (p->filteredlen >0) + return TRUE; + + return camel_stream_available(filter->source); +} + +static gboolean do_eos (CamelStream *stream) +{ + CamelStreamFilter *filter = (CamelStreamFilter *)stream; + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + + if (p->filteredlen >0) + return FALSE; + + return camel_stream_eos(filter->source); +} + +static void do_close (CamelStream *stream) +{ + CamelStreamFilter *filter = (CamelStreamFilter *)stream; + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + + p->filteredlen = 0; + camel_stream_close(filter->source); +} + +static void do_reset (CamelStream *stream) +{ + CamelStreamFilter *filter = (CamelStreamFilter *)stream; + struct _CamelStreamFilterPrivate *p = _PRIVATE(filter); + struct _filter *f; + + p->filteredlen = 0; + camel_stream_reset(filter->source); + + /* and reset filters */ + f = p->filters; + while (f) { + camel_mime_filter_reset(f->filter); + f = f->next; + } +} + |