From 6813ebfc61608a8dd9703b2e2be39365711f9f33 Mon Sep 17 00:00:00 2001 From: Michael Zucci Date: Tue, 7 Nov 2000 12:48:36 +0000 Subject: Oops, forgot to commit. New stream/filter for doing cool stuff. svn path=/trunk/; revision=6480 --- camel/camel-mime-filter-bestenc.c | 246 ++++++++++++++++++++++++++++++++++++++ camel/camel-mime-filter-bestenc.h | 80 +++++++++++++ camel/camel-stream-null.c | 90 ++++++++++++++ camel/camel-stream-null.h | 44 +++++++ 4 files changed, 460 insertions(+) create mode 100644 camel/camel-mime-filter-bestenc.c create mode 100644 camel/camel-mime-filter-bestenc.h create mode 100644 camel/camel-stream-null.c create mode 100644 camel/camel-stream-null.h (limited to 'camel') diff --git a/camel/camel-mime-filter-bestenc.c b/camel/camel-mime-filter-bestenc.c new file mode 100644 index 0000000000..d3db9a2a3f --- /dev/null +++ b/camel/camel-mime-filter-bestenc.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2000 Helix Code Inc. + * + * Authors: Michael Zucchi + * + * 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-mime-filter-bestenc.h" + +static void camel_mime_filter_bestenc_class_init (CamelMimeFilterBestencClass *klass); +static void camel_mime_filter_bestenc_init (CamelMimeFilter *obj); + +static CamelMimeFilterClass *camel_mime_filter_bestenc_parent; + +CamelType +camel_mime_filter_bestenc_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_mime_filter_get_type (), "CamelMimeFilterBestenc", + sizeof (CamelMimeFilterBestenc), + sizeof (CamelMimeFilterBestencClass), + (CamelObjectClassInitFunc) camel_mime_filter_bestenc_class_init, + NULL, + (CamelObjectInitFunc) camel_mime_filter_bestenc_init, + NULL); + } + + return type; +} + +static void +reset(CamelMimeFilter *mf) +{ + CamelMimeFilterBestenc *f = (CamelMimeFilterBestenc *)mf; + + f->count0 = 0; + f->count8 = 0; + f->countline = 0; + f->total = 0; + f->lastc = ~0; + f->crlfnoorder = FALSE; + camel_charset_init(&f->charset); +} + +static void +filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace) +{ + CamelMimeFilterBestenc *f = (CamelMimeFilterBestenc *)mf; + register unsigned char *p, *pend; + + f->total += len; + + if (f->flags & CAMEL_BESTENC_GET_ENCODING) { + register unsigned int /* hopefully reg's are assinged in the order they appear? */ + c, + lastc=f->lastc, + countline=f->countline, + count0=f->count0, + count8 = f->count8; + + /* See rfc2045 section 2 for definitions of 7bit/8bit/binary */ + p = in; + pend = p + len; + while (pflags & CAMEL_BESTENC_LF_IS_CRLF)) { + f->crlfnoorder = TRUE; + } + + /* check for end of line */ + if (c == '\n') { + /* check for wild '\n's in canonical format stream */ + if (lastc == '\r' || (f->flags & CAMEL_BESTENC_LF_IS_CRLF)) { + if (countline > f->maxline) + f->maxline = countline; + countline = 0; + } else { + f->crlfnoorder = TRUE; + } + } else { + countline++; + } + lastc = c; + } + f->count8 = count8; + f->count0 = count0; + f->countline = countline; + f->lastc = lastc; + } + + if (f->flags & CAMEL_BESTENC_GET_CHARSET) + camel_charset_step(&f->charset, in, len); + + *out = in; + *outlen = len; + *outprespace = prespace; +} + +static void +complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace) +{ + CamelMimeFilterBestenc *f = (CamelMimeFilterBestenc *)mf; + + filter(mf, in, len, prespace, out, outlen, outprespace); + + if (f->countline > f->maxline) + f->maxline = f->countline; + f->countline = 0; +} + +static void +camel_mime_filter_bestenc_class_init (CamelMimeFilterBestencClass *klass) +{ + CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass; + + camel_mime_filter_bestenc_parent = (CamelMimeFilterClass *)(camel_type_get_global_classfuncs (camel_mime_filter_get_type ())); + + filter_class->reset = reset; + filter_class->filter = filter; + filter_class->complete = complete; +} + +static void +camel_mime_filter_bestenc_init (CamelMimeFilter *f) +{ + reset(f); +} + +/** + * camel_mime_filter_bestenc_new: + * @flags: A bitmask of data required. + * + * Create a new CamelMimeFilterBestenc object. + * + * Return value: + **/ +CamelMimeFilterBestenc * +camel_mime_filter_bestenc_new (unsigned int flags) +{ + CamelMimeFilterBestenc *new = (CamelMimeFilterBestenc *)camel_object_new(camel_mime_filter_bestenc_get_type()); + new->flags = flags; + return new; +} + +/** + * camel_mime_filter_bestenc_get_best_encoding: + * @f: + * @required: maximum level of output encoding allowed. + * + * Return the best encoding, given specific constraints, that can be used to + * encode a stream of bytes. + * + * Return value: + **/ +CamelMimePartEncodingType +camel_mime_filter_bestenc_get_best_encoding(CamelMimeFilterBestenc *f, CamelBestencEncoding required) +{ + CamelMimePartEncodingType bestenc; + +#if 0 + printf("count0 = %d, count8 = %d, total = %d\n", f->count0, f->count8, f->total); + printf("maxline = %d, crlfnoorder = %s\n", f->maxline, f->crlfnoorder?"TRUE":"FALSE"); + printf(" %d%% require encoding?\n", (f->count0+f->count8)*100 / f->total); +#endif + + /* if we need to encode, see how we do it */ + if (required == CAMEL_BESTENC_BINARY) + bestenc = CAMEL_MIME_PART_ENCODING_BINARY; + else if (f->count8 + f->count0 >= (f->total*17/100)) + bestenc = CAMEL_MIME_PART_ENCODING_BASE64; + else + bestenc = CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE; + + /* if we have nocrlf order, or long lines, we need to encode always */ + if (f->crlfnoorder || f->maxline >= 998) + return bestenc; + + /* if we have no 8 bit chars or nul's, we can just use 7 bit */ + if (f->count8 + f->count0 == 0) + return CAMEL_MIME_PART_ENCODING_7BIT; + + /* otherwise, we see if we can use 8 bit, or not */ + switch(required) { + case CAMEL_BESTENC_7BIT: + return bestenc; + case CAMEL_BESTENC_8BIT: + case CAMEL_BESTENC_BINARY: + if (f->count0 == 0) + return CAMEL_MIME_PART_ENCODING_8BIT; + else + return bestenc; + } + + return CAMEL_MIME_PART_ENCODING_DEFAULT; +} + +/** + * camel_mime_filter_bestenc_get_best_charset: + * @f: + * + * Gets the best charset that can be used to contain this content. + * + * Return value: + **/ +const char * +camel_mime_filter_bestenc_get_best_charset(CamelMimeFilterBestenc *f) +{ + return camel_charset_best_name(&f->charset); +} + +/** + * camel_mime_filter_bestenc_set_flags: + * @f: + * @flags: + * + * Set the flags for subsequent operations. + **/ +void +camel_mime_filter_bestenc_set_flags(CamelMimeFilterBestenc *f, unsigned int flags) +{ + f->flags = flags; +} diff --git a/camel/camel-mime-filter-bestenc.h b/camel/camel-mime-filter-bestenc.h new file mode 100644 index 0000000000..32eea23afe --- /dev/null +++ b/camel/camel-mime-filter-bestenc.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2000 Helix Code Inc. + * + * Authors: Michael Zucchi + * + * 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. + */ + +#ifndef _CAMEL_MIME_FILTER_BESTENC_H +#define _CAMEL_MIME_FILTER_BESTENC_H + +#include +#include +#include + +#define CAMEL_MIME_FILTER_BESTENC(obj) CAMEL_CHECK_CAST (obj, camel_mime_filter_bestenc_get_type (), CamelMimeFilterBestenc) +#define CAMEL_MIME_FILTER_BESTENC_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_mime_filter_bestenc_get_type (), CamelMimeFilterBestencClass) +#define IS_CAMEL_MIME_FILTER_BESTENC(obj) CAMEL_CHECK_TYPE (obj, camel_mime_filter_bestenc_get_type ()) + +typedef struct _CamelMimeFilterBestencClass CamelMimeFilterBestencClass; + +enum _CamelBestencRequired { + CAMEL_BESTENC_GET_ENCODING = 1<<0, + CAMEL_BESTENC_GET_CHARSET = 1<<1, + + /* do we treat 'lf' as if it were crlf? */ + CAMEL_BESTENC_LF_IS_CRLF = 1<<8 +}; +typedef enum _CamelBestencRequired CamelBestencRequired; + +enum _CamelBestencEncoding { + CAMEL_BESTENC_7BIT, + CAMEL_BESTENC_8BIT, + CAMEL_BESTENC_BINARY, +}; +typedef enum _CamelBestencEncoding CamelBestencEncoding; + +struct _CamelMimeFilterBestenc { + CamelMimeFilter parent; + + unsigned int flags; /* our creation flags, see above */ + + unsigned int count0; /* count of NUL characters */ + unsigned int count8; /* count of 8 bit characters */ + unsigned int total; /* total characters read */ + + unsigned int lastc; /* the last character read */ + int crlfnoorder; /* if crlf's occured where they shouldn't have */ + + unsigned int countline; /* current count of characters on a given line */ + unsigned int maxline; /* max length of any line */ + + CamelCharset charset; /* used to determine the best charset to use */ +}; + +struct _CamelMimeFilterBestencClass { + CamelMimeFilterClass parent_class; +}; + +guint camel_mime_filter_bestenc_get_type (void); +CamelMimeFilterBestenc *camel_mime_filter_bestenc_new (unsigned int flags); + + +CamelMimePartEncodingType camel_mime_filter_bestenc_get_best_encoding(CamelMimeFilterBestenc *f, CamelBestencEncoding required); +const char * camel_mime_filter_bestenc_get_best_charset(CamelMimeFilterBestenc *f); +void camel_mime_filter_bestenc_set_flags(CamelMimeFilterBestenc *f, unsigned int flags); + +#endif /* ! _CAMEL_MIME_FILTER_BESTENC_H */ diff --git a/camel/camel-stream-null.c b/camel/camel-stream-null.c new file mode 100644 index 0000000000..34cc67ec7c --- /dev/null +++ b/camel/camel-stream-null.c @@ -0,0 +1,90 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ +/* camel-stream.c : abstract class for a stream */ + +/* + * Author: + * Michael Zucchi + * + * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include "camel-stream-null.h" + +static CamelObjectClass *parent_class = NULL; + +/* Returns the class for a CamelStream */ +#define CS_CLASS(so) CAMEL_STREAM_NULL_CLASS(CAMEL_OBJECT_GET_CLASS(so)) + +/* dummy implementations, for a NULL stream */ +static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n) { return 0; } +static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n) { return n; } +static int stream_close (CamelStream *stream) { return 0; } +static int stream_flush (CamelStream *stream) { return 0; } +static gboolean stream_eos (CamelStream *stream) { return TRUE; } +static int stream_reset (CamelStream *stream) { return 0; } + +static void +camel_stream_null_class_init (CamelStreamClass *camel_stream_null_class) +{ + CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_stream_null_class; + + parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE ); + + /* virtual method definition */ + camel_stream_class->read = stream_read; + camel_stream_class->write = stream_write; + camel_stream_class->close = stream_close; + camel_stream_class->flush = stream_flush; + camel_stream_class->eos = stream_eos; + camel_stream_class->reset = stream_reset; +} + +CamelType +camel_stream_null_get_type (void) +{ + static CamelType camel_stream_null_type = CAMEL_INVALID_TYPE; + + if (camel_stream_null_type == CAMEL_INVALID_TYPE) { + camel_stream_null_type = camel_type_register( camel_stream_get_type(), + "CamelStreamNull", + sizeof( CamelStreamNull ), + sizeof( CamelStreamNullClass ), + (CamelObjectClassInitFunc) camel_stream_null_class_init, + NULL, + NULL, + NULL ); + } + + return camel_stream_null_type; +} + +/** + * camel_stream_fs_new_with_fd: + * @fd: a file descriptor + * + * Returns a NULL stream. A null stream is always at eof, and + * always returns success for all reads and writes. + * + * Return value: the stream + **/ +CamelStreamNull * +camel_stream_null_new(void) +{ + return (CamelStreamNull *)camel_object_new(camel_stream_null_get_type ()); +} diff --git a/camel/camel-stream-null.h b/camel/camel-stream-null.h new file mode 100644 index 0000000000..d67d193991 --- /dev/null +++ b/camel/camel-stream-null.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2000 Helix Code Inc. + * + * Authors: Michael Zucchi + * + * 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. + */ + +#ifndef _CAMEL_STREAM_NULL_H +#define _CAMEL_STREAM_NULL_H + +#include + +#define CAMEL_STREAM_NULL(obj) CAMEL_CHECK_CAST (obj, camel_stream_null_get_type (), CamelStreamNull) +#define CAMEL_STREAM_NULL_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_stream_null_get_type (), CamelStreamNullClass) +#define IS_CAMEL_STREAM_NULL(obj) CAMEL_CHECK_TYPE (obj, camel_stream_null_get_type ()) + +typedef struct _CamelStreamNullClass CamelStreamNullClass; + +struct _CamelStreamNull { + CamelStream parent; +}; + +struct _CamelStreamNullClass { + CamelStreamClass parent_class; +}; + +guint camel_stream_null_get_type (void); + +CamelStreamNull *camel_stream_null_new (void); + +#endif /* ! _CAMEL_STREAM_NULL_H */ -- cgit