Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / camel / camel-mime-filter-from.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  *  Copyright (C) 2000 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
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include "camel-mime-filter-from.h"
30
31 #define d(x)
32
33 static void camel_mime_filter_from_class_init (CamelMimeFilterFromClass *klass);
34 static void camel_mime_filter_from_init       (CamelMimeFilterFrom *obj);
35
36 static CamelMimeFilterClass *camel_mime_filter_from_parent;
37
38 CamelType
39 camel_mime_filter_from_get_type (void)
40 {
41         static CamelType type = CAMEL_INVALID_TYPE;
42         
43         if (type == CAMEL_INVALID_TYPE) {
44                 type = camel_type_register (camel_mime_filter_get_type (), "CamelMimeFilterFrom",
45                                             sizeof (CamelMimeFilterFrom),
46                                             sizeof (CamelMimeFilterFromClass),
47                                             (CamelObjectClassInitFunc) camel_mime_filter_from_class_init,
48                                             NULL,
49                                             (CamelObjectInitFunc) camel_mime_filter_from_init,
50                                             NULL);
51         }
52         
53         return type;
54 }
55
56 struct fromnode {
57         struct fromnode *next;
58         char *pointer;
59 };
60
61 static void
62 complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
63 {
64         *out = in;
65         *outlen = len;
66         *outprespace = prespace;
67 }
68
69 /* Yes, it is complicated ... */
70 static void
71 filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
72 {
73         CamelMimeFilterFrom *f = (CamelMimeFilterFrom *)mf;
74         register char *inptr, *inend;
75         int left;
76         int midline = f->midline;
77         int fromcount = 0;
78         struct fromnode *head = NULL, *tail = (struct fromnode *)&head, *node;
79         char *outptr;
80
81         inptr = in;
82         inend = inptr+len;
83
84         d(printf("Filtering '%.*s'\n", len, in));
85
86         /* first, see if we need to escape any from's */
87         while (inptr<inend) {
88                 register int c = -1;
89
90                 if (midline)
91                         while (inptr < inend && (c = *inptr++) != '\n')
92                                 ;
93
94                 if (c == '\n' || !midline) {
95                         left = inend-inptr;
96                         if (left > 0) {
97                                 midline = TRUE;
98                                 if (left < 5) {
99                                         if (inptr[0] == 'F') {
100                                                 camel_mime_filter_backup(mf, inptr, left);
101                                                 midline = FALSE;
102                                                 inend = inptr;
103                                                 break;
104                                         }
105                                 } else {
106                                         if (!strncmp(inptr, "From ", 5)) {
107                                                 fromcount++;
108                                                 /* yes, we do alloc them on the stack ... at most we're going to get
109                                                    len / 7 of them anyway */
110                                                 node = alloca(sizeof(*node));
111                                                 node->pointer = inptr;
112                                                 node->next = NULL;
113                                                 tail->next = node;
114                                                 tail = node;
115                                                 inptr += 5;
116                                         }
117                                 }
118                         } else {
119                                 /* \n is at end of line, check next buffer */
120                                 midline = FALSE;
121                         }
122                 }
123         }
124
125         f->midline = midline;
126
127         if (fromcount > 0) {
128                 camel_mime_filter_set_size(mf, len + fromcount, FALSE);
129                 node = head;
130                 inptr = in;
131                 outptr = mf->outbuf;
132                 while (node) {
133                         memcpy(outptr, inptr, node->pointer - inptr);
134                         outptr += node->pointer - inptr;
135                         *outptr++ = '>';
136                         inptr = node->pointer;
137                         node = node->next;
138                 }
139                 memcpy(outptr, inptr, inend - inptr);
140                 outptr += inend - inptr;
141                 *out = mf->outbuf;
142                 *outlen = outptr - mf->outbuf;
143                 *outprespace = mf->outbuf - mf->outreal;
144
145                 d(printf("Filtered '%.*s'\n", *outlen, *out));
146         } else {
147                 *out = in;
148                 *outlen = inend - in;
149                 *outprespace = prespace;
150                 
151                 d(printf("Filtered '%.*s'\n", *outlen, *out));
152         }
153 }
154
155 static void
156 camel_mime_filter_from_class_init (CamelMimeFilterFromClass *klass)
157 {
158         CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass;
159         
160         camel_mime_filter_from_parent = CAMEL_MIME_FILTER_CLASS (camel_type_get_global_classfuncs (camel_mime_filter_get_type ()));
161
162         filter_class->filter = filter;
163         filter_class->complete = complete;
164 }
165
166 static void
167 camel_mime_filter_from_init (CamelMimeFilterFrom *obj)
168 {
169         ;
170 }
171
172
173 /**
174  * camel_mime_filter_from_new:
175  *
176  * Create a new #CamelMimeFilterFrom object.
177  * 
178  * Returns a new #CamelMimeFilterFrom object
179  **/
180 CamelMimeFilterFrom *
181 camel_mime_filter_from_new (void)
182 {
183         CamelMimeFilterFrom *new = CAMEL_MIME_FILTER_FROM ( camel_object_new (camel_mime_filter_from_get_type ()));
184         return new;
185 }
186
187 #if 0
188
189 #include <stdio.h>
190
191 int main(int argc, char **argv)
192 {
193         CamelMimeFilterFrom *f;
194         char *buffer;
195         int len, prespace;
196
197         g_tk_init(&argc, &argv);
198
199
200         f = camel_mime_filter_from_new();
201
202         buffer = "This is a test\nFrom Someone\nTo someone. From Someone else, From\n From blah\nFromblah\nBye! \nFrom ";
203         len = strlen(buffer);
204         prespace = 0;
205
206         printf("input = '%.*s'\n", len, buffer);
207         camel_mime_filter_filter(f, buffer, len, prespace, &buffer, &len, &prespace);
208         printf("output = '%.*s'\n", len, buffer);
209         buffer = "";
210         len = 0;
211         prespace = 0;
212         camel_mime_filter_complete(f, buffer, len, prespace, &buffer, &len, &prespace);
213         printf("complete = '%.*s'\n", len, buffer);
214         
215
216         return 0;
217 }
218
219 #endif