Initialize the gmime for upstream
[platform/upstream/gmime.git] / gmime / gmime-filter-windows.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*  GMime
3  *  Copyright (C) 2000-2012 Jeffrey Stedfast
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public License
7  *  as published by the Free Software Foundation; either version 2.1
8  *  of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
18  *  02110-1301, USA.
19  */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "gmime-filter-windows.h"
27 #include "gmime-charset.h"
28
29 #define d(x)
30
31
32 /**
33  * SECTION: gmime-filter-windows
34  * @title: GMimeFilterWindows
35  * @short_description: Determine if text is in a Microsoft Windows codepage
36  * @see_also: #GMimeFilter
37  *
38  * A #GMimeFilter used for determining if text marked as iso-8859-##
39  * is actually encoded in one of the Windows-CP125# charsets.
40  **/
41
42
43 static void g_mime_filter_windows_class_init (GMimeFilterWindowsClass *klass);
44 static void g_mime_filter_windows_init (GMimeFilterWindows *filter, GMimeFilterWindowsClass *klass);
45 static void g_mime_filter_windows_finalize (GObject *object);
46
47 static GMimeFilter *filter_copy (GMimeFilter *filter);
48 static void filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
49                            char **out, size_t *outlen, size_t *outprespace);
50 static void filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
51                              char **out, size_t *outlen, size_t *outprespace);
52 static void filter_reset (GMimeFilter *filter);
53
54
55 static GMimeFilterClass *parent_class = NULL;
56
57
58 GType
59 g_mime_filter_windows_get_type (void)
60 {
61         static GType type = 0;
62         
63         if (!type) {
64                 static const GTypeInfo info = {
65                         sizeof (GMimeFilterWindowsClass),
66                         NULL, /* base_class_init */
67                         NULL, /* base_class_finalize */
68                         (GClassInitFunc) g_mime_filter_windows_class_init,
69                         NULL, /* class_finalize */
70                         NULL, /* class_data */
71                         sizeof (GMimeFilterWindows),
72                         0,    /* n_preallocs */
73                         (GInstanceInitFunc) g_mime_filter_windows_init,
74                 };
75                 
76                 type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterWindows", &info, 0);
77         }
78         
79         return type;
80 }
81
82
83 static void
84 g_mime_filter_windows_class_init (GMimeFilterWindowsClass *klass)
85 {
86         GObjectClass *object_class = G_OBJECT_CLASS (klass);
87         GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
88         
89         parent_class = g_type_class_ref (GMIME_TYPE_FILTER);
90         
91         object_class->finalize = g_mime_filter_windows_finalize;
92         
93         filter_class->copy = filter_copy;
94         filter_class->filter = filter_filter;
95         filter_class->complete = filter_complete;
96         filter_class->reset = filter_reset;
97 }
98
99 static void
100 g_mime_filter_windows_init (GMimeFilterWindows *filter, GMimeFilterWindowsClass *klass)
101 {
102         filter->claimed_charset = NULL;
103         filter->is_windows = FALSE;
104 }
105
106 static void
107 g_mime_filter_windows_finalize (GObject *object)
108 {
109         GMimeFilterWindows *filter = (GMimeFilterWindows *) object;
110         
111         g_free (filter->claimed_charset);
112         
113         G_OBJECT_CLASS (parent_class)->finalize (object);
114 }
115
116
117 static GMimeFilter *
118 filter_copy (GMimeFilter *filter)
119 {
120         GMimeFilterWindows *windows = (GMimeFilterWindows *) filter;
121         
122         return g_mime_filter_windows_new (windows->claimed_charset);
123 }
124
125 static void
126 filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
127                char **out, size_t *outlen, size_t *outprespace)
128 {
129         GMimeFilterWindows *windows = (GMimeFilterWindows *) filter;
130         register unsigned char *inptr;
131         unsigned char *inend;
132         
133         if (!windows->is_windows) {
134                 inptr = (unsigned char *) in;
135                 inend = inptr + len;
136                 
137                 while (inptr < inend) {
138                         register unsigned char c = *inptr++;
139                         
140                         if (c >= 128 && c <= 159) {
141                                 d(g_warning ("Encountered text encoded in a Windows charset trying "
142                                              "to pass itself off as being encoded in %s",
143                                              windows->claimed_charset));
144                                 windows->is_windows = TRUE;
145                                 break;
146                         }
147                 }
148         }
149         
150         *out = in;
151         *outlen = len;
152         *outprespace = prespace;        
153 }
154
155 static void 
156 filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
157                  char **out, size_t *outlen, size_t *outprespace)
158 {
159         filter_filter (filter, in, len, prespace, out, outlen, outprespace);
160 }
161
162 static void
163 filter_reset (GMimeFilter *filter)
164 {
165         GMimeFilterWindows *windows = (GMimeFilterWindows *) filter;
166         
167         windows->is_windows = FALSE;
168 }
169
170
171 /**
172  * g_mime_filter_windows_new:
173  * @claimed_charset: charset that a text stream claims to be
174  *
175  * Creates a new GMimeFilterWindows filter. When a stream of text has
176  * been filtered, it can be determined whether or not said text stream
177  * was in @claimed_charset or the equivalent Windows-CP125# charset.
178  *
179  * Returns: a new windows filter.
180  **/
181 GMimeFilter *
182 g_mime_filter_windows_new (const char *claimed_charset)
183 {
184         GMimeFilterWindows *new;
185         
186         g_return_val_if_fail (claimed_charset != NULL, NULL);
187         
188         new = g_object_newv (GMIME_TYPE_FILTER_WINDOWS, 0, NULL);
189         new->claimed_charset = g_strdup (claimed_charset);
190         
191         return (GMimeFilter *) new;
192 }
193
194
195 /**
196  * g_mime_filter_windows_is_windows_charset:
197  * @filter: windows filter object
198  *
199  * Determines whether or not a Windows-CP125# charset has been
200  * detected so far.
201  *
202  * Returns: %TRUE if the filtered stream has been detected to contain
203  * Windows-CP125# characters or %FALSE otherwise.
204  **/
205 gboolean
206 g_mime_filter_windows_is_windows_charset (GMimeFilterWindows *filter)
207 {
208         g_return_val_if_fail (GMIME_IS_FILTER_WINDOWS (filter), FALSE);
209         
210         return filter->is_windows;
211 }
212
213
214 /**
215  * g_mime_filter_windows_real_charset:
216  * @filter: windows filter object
217  *
218  * Figures out the real charset that the text is encoded in based on whether or not Windows-CP125# characters were found.
219  *
220  * Returns: a const string pointer to the claimed charset if filtered
221  * text stream was found not to contain any Windows-CP125# characters
222  * or the proper Windows-CP125# charset.
223  **/
224 const char *
225 g_mime_filter_windows_real_charset (GMimeFilterWindows *filter)
226 {
227         g_return_val_if_fail (GMIME_IS_FILTER_WINDOWS (filter), NULL);
228         
229         if (filter->is_windows)
230                 return g_mime_charset_iso_to_windows (filter->claimed_charset);
231         else
232                 return filter->claimed_charset;
233 }