Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / camel / camel-mime-filter-html.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  *  Copyright (C) 2001 Ximian Inc.
4  *
5  *  Authors: Michael Zucchi <notzed@ximian.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2 of the GNU Lesser General Public
9  * License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include <fcntl.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30
31 #include "camel-html-parser.h"
32 #include "camel-mime-filter-html.h"
33
34 #define d(x)
35
36 static void camel_mime_filter_html_class_init (CamelMimeFilterHTMLClass *klass);
37 static void camel_mime_filter_html_init       (CamelObject *o);
38 static void camel_mime_filter_html_finalize   (CamelObject *o);
39
40 static CamelMimeFilterClass *camel_mime_filter_html_parent;
41
42 struct _CamelMimeFilterHTMLPrivate {
43         CamelHTMLParser *ctxt;
44 };
45
46 /* ********************************************************************** */
47
48 #if 0
49
50 /* well we odnt use this stuff yet */
51
52 #define ARRAY_LEN(x) (sizeof(x)/sizeof((x)[0]))
53
54 static struct {
55         char *element;
56         char *remap;
57 } map_start[] = {
58         { "p", "\n\n" },
59         { "br", "\n" },
60         { "h1", "\n" }, { "h2", "\n" }, { "h3", "\n" }, { "h4", "\n" }, { "h5", "\n" }, { "h6", "\n" },
61 };
62
63
64 static struct {
65         char *element;
66         char *remap;
67 } map_end[] = {
68         { "h1", "\n" }, { "h2", "\n" }, { "h3", "\n" }, { "h4", "\n" }, { "h5", "\n" }, { "h6", "\n" },
69 };
70 #endif
71
72
73 /* ********************************************************************** */
74
75
76 CamelType
77 camel_mime_filter_html_get_type (void)
78 {
79         static CamelType type = CAMEL_INVALID_TYPE;
80         
81         if (type == CAMEL_INVALID_TYPE) {
82                 type = camel_type_register (camel_mime_filter_get_type (), "CamelMimeFilterHTML",
83                                             sizeof (CamelMimeFilterHTML),
84                                             sizeof (CamelMimeFilterHTMLClass),
85                                             (CamelObjectClassInitFunc) camel_mime_filter_html_class_init,
86                                             NULL,
87                                             (CamelObjectInitFunc) camel_mime_filter_html_init,
88                                             (CamelObjectFinalizeFunc) camel_mime_filter_html_finalize);
89         }
90         
91         return type;
92 }
93
94 static void
95 camel_mime_filter_html_finalize(CamelObject *o)
96 {
97         CamelMimeFilterHTML *f = (CamelMimeFilterHTML *)o;
98
99         camel_object_unref((CamelObject *)f->priv->ctxt);
100         g_free(f->priv);
101 }
102
103 static void
104 camel_mime_filter_html_init       (CamelObject *o)
105 {
106         CamelMimeFilterHTML *f = (CamelMimeFilterHTML *)o;
107
108         f->priv = g_malloc0(sizeof(*f->priv));
109         f->priv->ctxt = camel_html_parser_new();
110 }
111
112 static void
113 run(CamelMimeFilter *mf, char *in, size_t inlen, size_t prespace, char **out, size_t *outlenptr, size_t *outprespace, int last)
114 {
115         CamelMimeFilterHTML *f = (CamelMimeFilterHTML *) mf;
116         camel_html_parser_t state;
117         char *outp;
118         
119         d(printf("converting html:\n%.*s\n", (int)inlen, in));
120         
121         /* We should generally shrink the data, but this'll do */
122         camel_mime_filter_set_size (mf, inlen * 2 + 256, FALSE);
123         outp = mf->outbuf;
124         
125         camel_html_parser_set_data (f->priv->ctxt, in, inlen, last);
126         do {
127                 const char *data;
128                 int len;
129                 
130                 state = camel_html_parser_step(f->priv->ctxt, &data, &len);
131                 
132                 switch(state) {
133                 case CAMEL_HTML_PARSER_DATA:
134                 case CAMEL_HTML_PARSER_ENT:
135                         memcpy(outp, data, len);
136                         outp += len;
137                         break;
138                 case CAMEL_HTML_PARSER_ELEMENT:
139                         /* FIXME: do some whitespace processing here */
140                         break;
141                 default:
142                         /* ignore everything else */
143                         break;
144                 }
145         } while (state != CAMEL_HTML_PARSER_EOF && state != CAMEL_HTML_PARSER_EOD);
146
147         *out = mf->outbuf;
148         *outlenptr = outp - mf->outbuf;
149         *outprespace = mf->outbuf - mf->outreal;
150
151         d(printf("converted html end:\n%.*s\n", (int)*outlenptr, *out));
152 }
153
154 static void
155 complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlenptr, size_t *outprespace)
156 {
157         run(mf, in, len, prespace, out, outlenptr, outprespace, TRUE);
158 }
159
160 static void
161 filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlenptr, size_t *outprespace)
162 {
163         run(mf, in, len, prespace, out, outlenptr, outprespace, FALSE);
164 }
165
166 static void
167 reset(CamelMimeFilter *mf)
168 {
169         CamelMimeFilterHTML *f = (CamelMimeFilterHTML *)mf;
170
171         camel_object_unref((CamelObject *)f->priv->ctxt);
172         f->priv->ctxt = camel_html_parser_new();
173 }
174
175 static void
176 camel_mime_filter_html_class_init (CamelMimeFilterHTMLClass *klass)
177 {
178         CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass;
179         
180         camel_mime_filter_html_parent = CAMEL_MIME_FILTER_CLASS (camel_type_get_global_classfuncs (camel_mime_filter_get_type ()));
181
182         filter_class->reset = reset;
183         filter_class->filter = filter;
184         filter_class->complete = complete;
185 }
186
187
188 /**
189  * camel_mime_filter_html_new:
190  *
191  * Create a new #CamelMimeFilterHTML object.
192  * 
193  * Returns a new #CamelMimeFilterHTML object
194  **/
195 CamelMimeFilterHTML *
196 camel_mime_filter_html_new (void)
197 {
198         CamelMimeFilterHTML *new = CAMEL_MIME_FILTER_HTML ( camel_object_new (camel_mime_filter_html_get_type ()));
199         return new;
200 }