From ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Mon, 16 Dec 2002 15:05:06 +0000 Subject: #include some headers we had forgotten to add previously, also added 2002-12-16 Jeffrey Stedfast * camel.h: #include some headers we had forgotten to add previously, also added camel-mime-filter-enriched.h. * camel-mime-filter-enriched.[c,h]: New stream filter to convert text/enriched and text/richtext into HTML. svn path=/trunk/; revision=19124 --- camel/ChangeLog | 8 + camel/Makefile.am | 2 + camel/camel-mime-filter-enriched.c | 375 +++++++++++++++++++++++++++++++++++++ camel/camel-mime-filter-enriched.h | 66 +++++++ camel/camel-mime-filter-tohtml.c | 2 +- camel/camel.h | 3 + 6 files changed, 455 insertions(+), 1 deletion(-) create mode 100644 camel/camel-mime-filter-enriched.c create mode 100644 camel/camel-mime-filter-enriched.h (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index 3c115e6232..e37403899b 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,11 @@ +2002-12-16 Jeffrey Stedfast + + * camel.h: #include some headers we had forgotten to add + previously, also added camel-mime-filter-enriched.h. + + * camel-mime-filter-enriched.[c,h]: New stream filter to convert + text/enriched and text/richtext into HTML. + 2002-12-15 Jeffrey Stedfast * camel-multipart-signed.c (camel_multipart_signed_verify): Don't diff --git a/camel/Makefile.am b/camel/Makefile.am index df98ed5d1a..db5784fadd 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -56,6 +56,7 @@ libcamel_la_SOURCES = \ camel-mime-filter-chomp.c \ camel-mime-filter-canon.c \ camel-mime-filter-crlf.c \ + camel-mime-filter-enriched.c \ camel-mime-filter-from.c \ camel-mime-filter-html.c \ camel-mime-filter-tohtml.c \ @@ -157,6 +158,7 @@ libcamelinclude_HEADERS = \ camel-mime-filter-chomp.h \ camel-mime-filter-canon.h \ camel-mime-filter-crlf.h \ + camel-mime-filter-enriched.h \ camel-mime-filter-from.h \ camel-mime-filter-html.h \ camel-mime-filter-tohtml.h \ diff --git a/camel/camel-mime-filter-enriched.c b/camel/camel-mime-filter-enriched.c new file mode 100644 index 0000000000..7f6918bd68 --- /dev/null +++ b/camel/camel-mime-filter-enriched.c @@ -0,0 +1,375 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast + * + * Copyright 2002 Ximian, Inc. (www.ximian.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 Street #330, Boston, MA 02111-1307, USA. + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "string-utils.h" + +#include "camel-mime-filter-enriched.h" + +static struct { + char *enriched; + char *html; +} enriched_tags[] = { + { "bold", "" }, + { "/bold", "" }, + { "italic", "" }, + { "/italic", "" }, + { "fixed", "" }, + { "/fixed", "" }, + { "smaller", "" }, + { "/smaller", "" }, + { "bigger", "" }, + { "/bigger", "" }, + { "underline", "" }, + { "/underline", "" }, + { "center", "

" }, + { "/center", "

" }, + { "flushleft", "

" }, + { "/flushleft", "

" }, + { "flushright", "

" }, + { "/flushright", "

" }, + { "excerpt", "
" }, + { "/excerpt", "
" }, + { "paragraph", "

" }, + { "signature", "

" }, + { "/signature", "
" }, + { "comment", "" }, + { "param", "" }, + { "np", "
" } +}; + +#define NUM_ENRICHED_TAGS (sizeof (enriched_tags) / sizeof (enriched_tags[0])) + +static GHashTable *enriched_hash = NULL; + + +static void camel_mime_filter_enriched_class_init (CamelMimeFilterEnrichedClass *klass); +static void camel_mime_filter_enriched_init (CamelMimeFilterEnriched *filter); +static void camel_mime_filter_enriched_finalize (CamelObject *obj); + +static void filter_filter (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, + char **out, size_t *outlen, size_t *outprespace); +static void filter_complete (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, + char **out, size_t *outlen, size_t *outprespace); +static void filter_reset (CamelMimeFilter *filter); + + +static CamelMimeFilterClass *parent_class = NULL; + + +CamelType +camel_mime_filter_enriched_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_mime_filter_get_type (), + "CamelMimeFilterEnriched", + sizeof (CamelMimeFilterEnriched), + sizeof (CamelMimeFilterEnrichedClass), + (CamelObjectClassInitFunc) camel_mime_filter_enriched_class_init, + NULL, + (CamelObjectInitFunc) camel_mime_filter_enriched_init, + (CamelObjectFinalizeFunc) camel_mime_filter_enriched_finalize); + } + + return type; +} + +static void +camel_mime_filter_enriched_class_init (CamelMimeFilterEnrichedClass *klass) +{ + CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass; + int i; + + parent_class = CAMEL_MIME_FILTER_CLASS (camel_mime_filter_get_type ()); + + filter_class->reset = filter_reset; + filter_class->filter = filter_filter; + filter_class->complete = filter_complete; + + if (!enriched_hash) { + enriched_hash = g_hash_table_new (g_strcase_hash, g_strcase_equal); + for (i = 0; i < NUM_ENRICHED_TAGS; i++) + g_hash_table_insert (enriched_hash, enriched_tags[i].enriched, + enriched_tags[i].html); + } +} + +static void +camel_mime_filter_enriched_finalize (CamelObject *obj) +{ + ; +} + +static void +camel_mime_filter_enriched_init (CamelMimeFilterEnriched *filter) +{ + filter->flags = 0; + filter->nofill = 0; +} + +#define IS_RICHTEXT CAMEL_MIME_FILTER_ENRICHED_IS_RICHTEXT + +static void +enriched_to_html (CamelMimeFilter *filter, char *in, size_t inlen, size_t prespace, + char **out, size_t *outlen, size_t *outprespace, gboolean flush) +{ + CamelMimeFilterEnriched *enriched = (CamelMimeFilterEnriched *) filter; + const char *tag, *inend, *outend; + register const char *inptr; + register char *outptr; + + camel_mime_filter_set_size (filter, inlen * 2 + 6, FALSE); + + inptr = in; + inend = in + inlen; + outptr = filter->outbuf; + outend = filter->outbuf + filter->outsize; + + loop: + do { + while (inptr < inend && outptr < outend && !strchr (" <>&\n", *inptr)) + *outptr++ = *inptr++; + + if (outptr == outend) + goto backup; + + if ((inptr + 1) >= inend) + break; + + switch (*inptr++) { + case ' ': + while (inptr < inend && (outptr + 7) < outend && *inptr == ' ') { + memcpy (outptr, " ", 6); + outptr += 6; + inptr++; + } + + if (outptr < outend) + *outptr++ = ' '; + + break; + case '\n': + if (!(enriched->flags & IS_RICHTEXT) && enriched->nofill <= 0) { + /* text/enriched */ + while (inptr < inend && (outptr + 4) < outend && *inptr == '\n') { + memcpy (outptr, "
", 4); + outptr += 4; + inptr++; + } + } else { + /* text/richtext */ + *outptr++ = ' '; + } + break; + case '>': + if ((outptr + 4) < outend) { + memcpy (outptr, ">", 4); + outptr += 4; + } else { + inptr--; + goto backup; + } + break; + case '&': + if ((outptr + 5) < outend) { + memcpy (outptr, "&", 5); + outptr += 5; + } else { + inptr--; + goto backup; + } + break; + case '<': + if (!(enriched->flags & IS_RICHTEXT)) { + /* text/enriched */ + if ((outptr + 4) < outend && *inptr == '<') { + memcpy (outptr, "<", 4); + outptr += 4; + inptr++; + break; + } else { + inptr--; + goto backup; + } + } else { + /* text/richtext */ + if ((inend - inptr) >= 3 && (outptr + 4) < outend) { + if (strncmp (inptr, "lt>", 3) == 0) { + memcpy (outptr, "<", 4); + outptr += 4; + inptr += 3; + break; + } else if (strncmp (inptr, "nl>", 3) == 0) { + memcpy (outptr, "
", 4); + outptr += 4; + inptr += 3; + break; + } + } else { + inptr--; + goto backup; + } + } + + tag = inptr; + while (inptr < inend && *inptr != '>') + inptr++; + + if (inptr == inend) { + inptr = tag - 1; + goto need_input; + } + + if (!strncmp (tag, "nofill>", 7)) { + if ((outptr + 5) < outend) { + memcpy (outptr, "
", 5);
+					enriched->nofill++;
+					outptr += 5;
+				} else {
+					inptr = tag - 1;
+					goto backup;
+				}
+			} else if (!strncmp (tag, "/nofill>", 8)) {
+				if ((outptr + 6) < outend) {
+					memcpy (outptr, "
", 6); + enriched->nofill--; + outptr += 6; + } else { + inptr = tag - 1; + goto backup; + } + } else { + const char *html_tag; + char *enriched_tag; + int len; + + enriched_tag = g_strndup (tag, (inptr - tag)); + html_tag = g_hash_table_lookup (enriched_hash, enriched_tag); + g_free (enriched_tag); + if (html_tag) { + len = strlen (html_tag); + if ((outptr + len) < outend) { + memcpy (outptr, html_tag, len); + outptr += len; + } else { + inptr = tag - 1; + goto backup; + } + } + } + + inptr++; + break; + default: + break; + } + } while (inptr < inend); + + need_input: + + /* the reason we ignore @flush here is because if there isn't + enough input to parse a tag, then there's nothing we can + do. */ + + if (inptr < inend) + camel_mime_filter_backup (filter, inptr, (unsigned) (inend - inptr)); + + *out = filter->outbuf; + *outlen = outptr - filter->outbuf; + *outprespace = filter->outpre; + + return; + + backup: + + if (flush) { + size_t offset, grow; + + grow = (inend - inptr) * 2 + 20; + offset = outptr - filter->outbuf; + camel_mime_filter_set_size (filter, filter->outsize + grow, TRUE); + outend = filter->outbuf + filter->outsize; + outptr = filter->outbuf + offset; + + goto loop; + } else { + camel_mime_filter_backup (filter, inptr, (unsigned) (inend - inptr)); + } + + *out = filter->outbuf; + *outlen = outptr - filter->outbuf; + *outprespace = filter->outpre; +} + +static void +filter_filter (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, + char **out, size_t *outlen, size_t *outprespace) +{ + enriched_to_html (filter, in, len, prespace, out, outlen, outprespace, FALSE); +} + +static void +filter_complete (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, + char **out, size_t *outlen, size_t *outprespace) +{ + enriched_to_html (filter, in, len, prespace, out, outlen, outprespace, TRUE); +} + +static void +filter_reset (CamelMimeFilter *filter) +{ + CamelMimeFilterEnriched *enriched = (CamelMimeFilterEnriched *) filter; + + enriched->nofill = 0; +} + + +/** + * camel_mime_filter_enriched_new: + * @flags: + * + * Creates a new CamelMimeFilterEnriched object. + * + * Returns a new CamelMimeFilter object. + **/ +CamelMimeFilter * +camel_mime_filter_enriched_new (guint32 flags) +{ + CamelMimeFilterEnriched *new; + int i; + + new = (CamelMimeFilterEnriched *) camel_object_new (CAMEL_TYPE_MIME_FILTER_ENRICHED); + new->flags = flags; + + return CAMEL_MIME_FILTER (new); +} diff --git a/camel/camel-mime-filter-enriched.h b/camel/camel-mime-filter-enriched.h new file mode 100644 index 0000000000..13c3ff7a7e --- /dev/null +++ b/camel/camel-mime-filter-enriched.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast + * + * Copyright 2002 Ximian, Inc. (www.ximian.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 Street #330, Boston, MA 02111-1307, USA. + * + */ + + +#ifndef __CAMEL_MIME_FILTER_ENRICHED_H__ +#define __CAMEL_MIME_FILTER_ENRICHED_H__ + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#include + +#define CAMEL_TYPE_MIME_FILTER_ENRICHED (camel_mime_filter_enriched_get_type ()) +#define CAMEL_MIME_FILTER_ENRICHED(obj) (CAMEL_CHECK_CAST (obj, CAMEL_TYPE_MIME_FILTER_ENRICHED, CamelMimeFilterEnriched)) +#define CAMEL_MIME_FILTER_ENRICHED_CLASS(klass) (CAMEL_CHECK_CLASS_CAST (klass, CAMEL_TYPE_MIME_FILTER_ENRICHED, CamelMimeFilterEnrichedClass)) +#define CAMEL_IS_MIME_FILTER_ENRICHED(obj) (CAMEL_CHECK_TYPE (obj, CAMEL_TYPE_MIME_FILTER_ENRICHED)) + + +#define CAMEL_MIME_FILTER_ENRICHED_IS_RICHTEXT (1 << 0) + + +typedef struct _CamelMimeFilterEnriched CamelMimeFilterEnriched; +typedef struct _CamelMimeFilterEnrichedClass CamelMimeFilterEnrichedClass; + +struct _CamelMimeFilterEnriched { + CamelMimeFilter parent_object; + + guint32 flags; + int nofill; +}; + +struct _CamelMimeFilterEnrichedClass { + CamelMimeFilterClass parent_class; + +}; + +CamelType camel_mime_filter_enriched_get_type (void); + +CamelMimeFilter *camel_mime_filter_enriched_new (guint32 flags); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CAMEL_MIME_FILTER_ENRICHED_H__ */ diff --git a/camel/camel-mime-filter-tohtml.c b/camel/camel-mime-filter-tohtml.c index ab6cca1fd9..a3494ba72f 100644 --- a/camel/camel-mime-filter-tohtml.c +++ b/camel/camel-mime-filter-tohtml.c @@ -259,7 +259,7 @@ html_convert (CamelMimeFilter *filter, char *in, size_t inlen, size_t prespace, #define CONVERT_URLS (CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES) if (html->flags & CONVERT_URLS) { - size_t matchlen, buflen, len; + size_t matchlen, buflen, len; urlmatch_t match; len = inptr - start; diff --git a/camel/camel.h b/camel/camel.h index 34214237f9..014e79fafd 100644 --- a/camel/camel.h +++ b/camel/camel.h @@ -45,7 +45,10 @@ extern "C" { #include #include #include +#include #include +#include +#include #include #include #include -- cgit v1.2.3