Extending test-client-custom-summary to try e_book_client_get_contacts_uids()
[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) 1999-2008 Novell, Inc. (www.novell.com)
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 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27
28 #include "camel-mime-filter-from.h"
29
30 #define CAMEL_MIME_FILTER_FROM_GET_PRIVATE(obj) \
31         (G_TYPE_INSTANCE_GET_PRIVATE \
32         ((obj), CAMEL_TYPE_MIME_FILTER_FROM, CamelMimeFilterFromPrivate))
33
34 #define d(x)
35
36 struct _CamelMimeFilterFromPrivate {
37         gboolean midline;       /* are we between lines? */
38 };
39
40 struct fromnode {
41         struct fromnode *next;
42         const gchar *pointer;
43 };
44
45 G_DEFINE_TYPE (CamelMimeFilterFrom, camel_mime_filter_from, CAMEL_TYPE_MIME_FILTER)
46
47 /* Yes, it is complicated ... */
48 static void
49 mime_filter_from_filter (CamelMimeFilter *mime_filter,
50                          const gchar *in,
51                          gsize len,
52                          gsize prespace,
53                          gchar **out,
54                          gsize *outlen,
55                          gsize *outprespace)
56 {
57         CamelMimeFilterFromPrivate *priv;
58         const gchar *inptr, *inend;
59         gint left;
60         gint fromcount = 0;
61         struct fromnode *head = NULL, *tail = (struct fromnode *) &head, *node;
62         gchar *outptr;
63
64         priv = CAMEL_MIME_FILTER_FROM_GET_PRIVATE (mime_filter);
65
66         inptr = in;
67         inend = inptr + len;
68
69         d (printf ("Filtering '%.*s'\n", len, in));
70
71         /* first, see if we need to escape any from's */
72         while (inptr < inend) {
73                 register gint c = -1;
74
75                 if (priv->midline)
76                         while (inptr < inend && (c = *inptr++) != '\n')
77                                 ;
78
79                 if (c == '\n' || !priv->midline) {
80                         left = inend - inptr;
81                         if (left > 0) {
82                                 priv->midline = TRUE;
83                                 if (left < 5) {
84                                         if (inptr[0] == 'F') {
85                                                 camel_mime_filter_backup (mime_filter, inptr, left);
86                                                 priv->midline = FALSE;
87                                                 inend = inptr;
88                                                 break;
89                                         }
90                                 } else {
91                                         if (!strncmp (inptr, "From ", 5)) {
92                                                 fromcount++;
93                                                 /* yes, we do alloc them on the stack ... at most we're going to get
94                                                  * len / 7 of them anyway */
95                                                 node = alloca (sizeof (*node));
96                                                 node->pointer = inptr;
97                                                 node->next = NULL;
98                                                 tail->next = node;
99                                                 tail = node;
100                                                 inptr += 5;
101                                         }
102                                 }
103                         } else {
104                                 /* \n is at end of line, check next buffer */
105                                 priv->midline = FALSE;
106                         }
107                 }
108         }
109
110         if (fromcount > 0) {
111                 camel_mime_filter_set_size (mime_filter, len + fromcount, FALSE);
112                 node = head;
113                 inptr = in;
114                 outptr = mime_filter->outbuf;
115                 while (node) {
116                         memcpy (outptr, inptr, node->pointer - inptr);
117                         outptr += node->pointer - inptr;
118                         *outptr++ = '>';
119                         inptr = node->pointer;
120                         node = node->next;
121                 }
122                 memcpy (outptr, inptr, inend - inptr);
123                 outptr += inend - inptr;
124                 *out = mime_filter->outbuf;
125                 *outlen = outptr - mime_filter->outbuf;
126                 *outprespace = mime_filter->outbuf - mime_filter->outreal;
127
128                 d (printf ("Filtered '%.*s'\n", *outlen, *out));
129         } else {
130                 *out = (gchar *) in;
131                 *outlen = inend - in;
132                 *outprespace = prespace;
133
134                 d (printf ("Filtered '%.*s'\n", *outlen, *out));
135         }
136 }
137
138 static void
139 mime_filter_from_complete (CamelMimeFilter *mime_filter,
140                            const gchar *in,
141                            gsize len,
142                            gsize prespace,
143                            gchar **out,
144                            gsize *outlen,
145                            gsize *outprespace)
146 {
147         *out = (gchar *) in;
148         *outlen = len;
149         *outprespace = prespace;
150 }
151
152 static void
153 camel_mime_filter_from_class_init (CamelMimeFilterFromClass *class)
154 {
155         CamelMimeFilterClass *mime_filter_class;
156
157         g_type_class_add_private (class, sizeof (CamelMimeFilterFromPrivate));
158
159         mime_filter_class = CAMEL_MIME_FILTER_CLASS (class);
160         mime_filter_class->filter = mime_filter_from_filter;
161         mime_filter_class->complete = mime_filter_from_complete;
162 }
163
164 static void
165 camel_mime_filter_from_init (CamelMimeFilterFrom *filter)
166 {
167         filter->priv = CAMEL_MIME_FILTER_FROM_GET_PRIVATE (filter);
168 }
169
170 /**
171  * camel_mime_filter_from_new:
172  *
173  * Create a new #CamelMimeFilterFrom object.
174  *
175  * Returns: a new #CamelMimeFilterFrom object
176  **/
177 CamelMimeFilter *
178 camel_mime_filter_from_new (void)
179 {
180         return g_object_new (CAMEL_TYPE_MIME_FILTER_FROM, NULL);
181 }
182
183 #if 0
184
185 #include <stdio.h>
186
187 gint main (gint argc, gchar **argv)
188 {
189         CamelMimeFilterFrom *f;
190         gchar *buffer;
191         gint len, prespace;
192
193         g_tk_init (&argc, &argv);
194
195         f = camel_mime_filter_from_new ();
196
197         buffer = "This is a test\nFrom Someone\nTo someone. From Someone else, From\n From blah\nFromblah\nBye! \nFrom ";
198         len = strlen (buffer);
199         prespace = 0;
200
201         printf ("input = '%.*s'\n", len, buffer);
202         camel_mime_filter_filter (f, buffer, len, prespace, &buffer, &len, &prespace);
203         printf ("output = '%.*s'\n", len, buffer);
204         buffer = "";
205         len = 0;
206         prespace = 0;
207         camel_mime_filter_complete (f, buffer, len, prespace, &buffer, &len, &prespace);
208         printf ("complete = '%.*s'\n", len, buffer);
209
210         return 0;
211 }
212
213 #endif