Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / camel / camel-mime-filter-linewrap.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: Jeffrey Stedfast <fejj@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 <ctype.h>
28
29 #include "camel-mime-filter-linewrap.h"
30
31
32 static void filter (CamelMimeFilter *f, char *in, size_t len, size_t prespace,
33                     char **out, size_t *outlen, size_t *outprespace);
34 static void complete (CamelMimeFilter *f, char *in, size_t len,
35                       size_t prespace, char **out, size_t *outlen,
36                       size_t *outprespace);
37 static void reset (CamelMimeFilter *f);
38
39
40 static void
41 camel_mime_filter_linewrap_class_init (CamelMimeFilterLinewrapClass *klass)
42 {
43         CamelMimeFilterClass *mime_filter_class =
44                 (CamelMimeFilterClass *) klass;
45         
46         mime_filter_class->filter = filter;
47         mime_filter_class->complete = complete;
48         mime_filter_class->reset = reset;
49 }
50
51 CamelType
52 camel_mime_filter_linewrap_get_type (void)
53 {
54         static CamelType type = CAMEL_INVALID_TYPE;
55         
56         if (type == CAMEL_INVALID_TYPE) {
57                 type = camel_type_register (camel_mime_filter_get_type(), "CamelMimeFilterLinewrap",
58                                             sizeof (CamelMimeFilterLinewrap),
59                                             sizeof (CamelMimeFilterLinewrapClass),
60                                             (CamelObjectClassInitFunc) camel_mime_filter_linewrap_class_init,
61                                             NULL,
62                                             NULL,
63                                             NULL);
64         }
65         
66         return type;
67 }
68
69 static void
70 filter (CamelMimeFilter *f, char *in, size_t len, size_t prespace,
71         char **out, size_t *outlen, size_t *outprespace)
72 {
73         CamelMimeFilterLinewrap *linewrap = (CamelMimeFilterLinewrap *)f;
74         char *inend, *p, *q;
75         int nchars = linewrap->nchars;
76         
77         /* we'll be adding chars here so we need a bigger buffer */
78         camel_mime_filter_set_size (f, 3 * len, FALSE);
79         
80         p = in;
81         q = f->outbuf;
82         inend = in + len;
83         
84         while (p < inend) {
85                 if (*p == '\n') {
86                         *q++ = *p++;
87                         nchars = 0;
88                 } else if (isspace (*p)) {
89                         if (nchars >= linewrap->wrap_len) {
90                                 *q++ = '\n';
91                                 p++;
92                                 nchars = 0;
93                         } else {
94                                 *q++ = *p++;
95                         }
96                 } else {
97                         *q++ = *p++;
98                         nchars++;
99                 }
100                 
101                 /* line is getting way too long, we must force a wrap here */
102                 if (nchars >= (linewrap->max_len - 1) && *p != '\n') {
103                         *q++ = '\n';
104                         *q++ = linewrap->indent;
105                         nchars = 0;
106                 }
107         }
108         
109         linewrap->nchars = nchars;
110         
111         *out = f->outbuf;
112         *outlen = q - f->outbuf;
113         *outprespace = f->outpre;
114 }
115
116 static void 
117 complete (CamelMimeFilter *f, char *in, size_t len, size_t prespace,
118           char **out, size_t *outlen, size_t *outprespace)
119 {
120         if (len)
121                 filter (f, in, len, prespace, out, outlen, outprespace);
122 }
123
124 static void
125 reset (CamelMimeFilter *f)
126 {
127         CamelMimeFilterLinewrap *linewrap = (CamelMimeFilterLinewrap *)f;
128         
129         linewrap->nchars = 0;
130 }
131
132 CamelMimeFilter *
133 camel_mime_filter_linewrap_new (guint preferred_len, guint max_len, char indent_char)
134 {
135         CamelMimeFilterLinewrap *linewrap =
136                 CAMEL_MIME_FILTER_LINEWRAP (camel_object_new (CAMEL_MIME_FILTER_LINEWRAP_TYPE));
137         
138         linewrap->indent = indent_char;
139         linewrap->wrap_len = preferred_len;
140         linewrap->max_len = max_len;
141         linewrap->nchars = 0;
142         
143         return (CamelMimeFilter *) linewrap;
144 }