Initialize the gmime for upstream
[platform/upstream/gmime.git] / gmime / gmime-disposition.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 <ctype.h>
27 #include <string.h>
28
29 #include "gmime-common.h"
30 #include "gmime-disposition.h"
31 #include "gmime-events.h"
32
33
34 /**
35  * SECTION: gmime-disposition
36  * @title: GMimeContentDisposition
37  * @short_description: Content-Disposition fields
38  * @see_also:
39  *
40  * A #GMimeContentDisposition represents the pre-parsed contents of a
41  * Content-Disposition header field.
42  **/
43
44
45 static void g_mime_content_disposition_class_init (GMimeContentDispositionClass *klass);
46 static void g_mime_content_disposition_init (GMimeContentDisposition *disposition, GMimeContentDispositionClass *klass);
47 static void g_mime_content_disposition_finalize (GObject *object);
48
49
50 static GObjectClass *parent_class = NULL;
51
52
53 GType
54 g_mime_content_disposition_get_type (void)
55 {
56         static GType type = 0;
57         
58         if (!type) {
59                 static const GTypeInfo info = {
60                         sizeof (GMimeContentDispositionClass),
61                         NULL, /* base_class_init */
62                         NULL, /* base_class_finalize */
63                         (GClassInitFunc) g_mime_content_disposition_class_init,
64                         NULL, /* class_finalize */
65                         NULL, /* class_data */
66                         sizeof (GMimeContentDisposition),
67                         0,    /* n_preallocs */
68                         (GInstanceInitFunc) g_mime_content_disposition_init,
69                 };
70                 
71                 type = g_type_register_static (G_TYPE_OBJECT, "GMimeContentDisposition", &info, 0);
72         }
73         
74         return type;
75 }
76
77
78 static void
79 g_mime_content_disposition_class_init (GMimeContentDispositionClass *klass)
80 {
81         GObjectClass *object_class = G_OBJECT_CLASS (klass);
82         
83         parent_class = g_type_class_ref (G_TYPE_OBJECT);
84         
85         object_class->finalize = g_mime_content_disposition_finalize;
86 }
87
88 static void
89 g_mime_content_disposition_init (GMimeContentDisposition *disposition, GMimeContentDispositionClass *klass)
90 {
91         disposition->param_hash = g_hash_table_new (g_mime_strcase_hash, g_mime_strcase_equal);
92         disposition->priv = g_mime_event_new ((GObject *) disposition);
93         disposition->disposition = NULL;
94         disposition->params = NULL;
95 }
96
97 static void
98 g_mime_content_disposition_finalize (GObject *object)
99 {
100         GMimeContentDisposition *disposition = (GMimeContentDisposition *) object;
101         
102         g_hash_table_destroy (disposition->param_hash);
103         g_mime_param_destroy (disposition->params);
104         g_mime_event_destroy (disposition->priv);
105         g_free (disposition->disposition);
106         
107         G_OBJECT_CLASS (parent_class)->finalize (object);
108 }
109
110
111 /**
112  * g_mime_content_disposition_new:
113  *
114  * Creates a new #GMimeContentDisposition object.
115  *
116  * Returns: a new #GMimeContentDisposition object.
117  **/
118 GMimeContentDisposition *
119 g_mime_content_disposition_new (void)
120 {
121         GMimeContentDisposition *disposition;
122         
123         disposition = g_object_newv (GMIME_TYPE_CONTENT_DISPOSITION, 0, NULL);
124         disposition->disposition = g_strdup (GMIME_DISPOSITION_ATTACHMENT);
125         
126         return disposition;
127 }
128
129
130 /**
131  * g_mime_content_disposition_new_from_string:
132  * @str: Content-Disposition field value or %NULL
133  *
134  * Creates a new #GMimeContentDisposition object.
135  *
136  * Returns: a new #GMimeContentDisposition object.
137  **/
138 GMimeContentDisposition *
139 g_mime_content_disposition_new_from_string (const char *str)
140 {
141         GMimeContentDisposition *disposition;
142         const char *inptr = str;
143         GMimeParam *param;
144         char *value;
145         
146         if (str == NULL)
147                 return g_mime_content_disposition_new ();
148         
149         disposition = g_object_newv (GMIME_TYPE_CONTENT_DISPOSITION, 0, NULL);
150         
151         /* get content disposition part */
152         
153         /* find ; or \0 */
154         while (*inptr && *inptr != ';')
155                 inptr++;
156         
157         value = g_strndup (str, (size_t) (inptr - str));
158         disposition->disposition = g_strstrip (value);
159         
160         /* parse the parameters, if any */
161         if (*inptr++ == ';' && *inptr) {
162                 param = disposition->params = g_mime_param_new_from_string (inptr);
163                 
164                 while (param) {
165                         g_hash_table_insert (disposition->param_hash, param->name, param);
166                         param = param->next;
167                 }
168         }
169         
170         return disposition;
171 }
172
173
174 /**
175  * g_mime_content_disposition_set_disposition:
176  * @disposition: a #GMimeContentDisposition object
177  * @value: disposition value
178  *
179  * Sets the disposition to @value which may be one of
180  * #GMIME_DISPOSITION_ATTACHMENT or #GMIME_DISPOSITION_INLINE or, by
181  * your choice, any other string which would indicate how the MIME
182  * part should be displayed by the MUA.
183  **/
184 void
185 g_mime_content_disposition_set_disposition (GMimeContentDisposition *disposition, const char *value)
186 {
187         char *buf;
188         
189         g_return_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition));
190         g_return_if_fail (value != NULL);
191         
192         buf = g_strdup (value);
193         g_free (disposition->disposition);
194         disposition->disposition = buf;
195         
196         g_mime_event_emit (disposition->priv, NULL);
197 }
198
199
200 /**
201  * g_mime_content_disposition_get_disposition:
202  * @disposition: a #GMimeContentDisposition object
203  *
204  * Gets the disposition or %NULL on fail.
205  *
206  * Returns: the disposition string which is probably one of
207  * #GMIME_DISPOSITION_ATTACHMENT or #GMIME_DISPOSITION_INLINE.
208  **/
209 const char *
210 g_mime_content_disposition_get_disposition (GMimeContentDisposition *disposition)
211 {
212         g_return_val_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition), NULL);
213         
214         return disposition->disposition;
215 }
216
217
218 /**
219  * g_mime_content_disposition_set_params:
220  * @disposition: a #GMimeContentDisposition object
221  * @params: a list of #GMimeParam objects
222  *
223  * Sets the Content-Disposition's parameter list.
224  **/
225 void
226 g_mime_content_disposition_set_params (GMimeContentDisposition *disposition, GMimeParam *params)
227 {
228         g_return_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition));
229         
230         /* destroy the current list/hash */
231         g_hash_table_remove_all (disposition->param_hash);
232         g_mime_param_destroy (disposition->params);
233         disposition->params = params;
234         
235         while (params != NULL) {
236                 g_hash_table_insert (disposition->param_hash, params->name, params);
237                 params = params->next;
238         }
239         
240         g_mime_event_emit (disposition->priv, NULL);
241 }
242
243
244 /**
245  * g_mime_content_disposition_get_params:
246  * @disposition: a #GMimeContentDisposition object
247  *
248  * Gets the Content-Disposition parameter list.
249  *
250  * Returns: the list of #GMimeParam's set on @disposition.
251  **/
252 const GMimeParam *
253 g_mime_content_disposition_get_params (GMimeContentDisposition *disposition)
254 {
255         g_return_val_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition), NULL);
256         
257         return disposition->params;
258 }
259
260
261 /**
262  * g_mime_content_disposition_set_parameter:
263  * @disposition: a #GMimeContentDisposition object
264  * @attribute: parameter name
265  * @value: parameter value
266  *
267  * Sets a parameter on the Content-Disposition.
268  **/
269 void
270 g_mime_content_disposition_set_parameter (GMimeContentDisposition *disposition, const char *attribute, const char *value)
271 {
272         GMimeParam *param = NULL;
273         
274         g_return_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition));
275         g_return_if_fail (attribute != NULL);
276         g_return_if_fail (value != NULL);
277         
278         if ((param = g_hash_table_lookup (disposition->param_hash, attribute))) {
279                 g_free (param->value);
280                 param->value = g_strdup (value);
281         } else {
282                 param = g_mime_param_new (attribute, value);
283                 disposition->params = g_mime_param_append_param (disposition->params, param);
284                 g_hash_table_insert (disposition->param_hash, param->name, param);
285         }
286         
287         g_mime_event_emit (disposition->priv, NULL);
288 }
289
290
291 /**
292  * g_mime_content_disposition_get_parameter:
293  * @disposition: a #GMimeContentDisposition object
294  * @attribute: parameter name
295  *
296  * Gets the value of the parameter @attribute, or %NULL on fail.
297  *
298  * Returns: the value of the parameter of name @attribute.
299  **/
300 const char *
301 g_mime_content_disposition_get_parameter (GMimeContentDisposition *disposition, const char *attribute)
302 {
303         GMimeParam *param;
304         
305         g_return_val_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition), NULL);
306         g_return_val_if_fail (attribute != NULL, NULL);
307         
308         if (!(param = g_hash_table_lookup (disposition->param_hash, attribute)))
309                 return NULL;
310         
311         return param->value;
312 }
313
314
315 /**
316  * g_mime_content_disposition_to_string:
317  * @disposition: a #GMimeContentDisposition object
318  * @fold: fold header if needed
319  *
320  * Allocates a string buffer containing the Content-Disposition header
321  * represented by the disposition object @disposition.
322  *
323  * Returns: a string containing the disposition header
324  **/
325 char *
326 g_mime_content_disposition_to_string (GMimeContentDisposition *disposition, gboolean fold)
327 {
328         GString *string;
329         char *header, *buf;
330         
331         g_return_val_if_fail (GMIME_IS_CONTENT_DISPOSITION (disposition), NULL);
332         
333         /* we need to have this so wrapping is correct */
334         string = g_string_new ("Content-Disposition: ");
335         
336         g_string_append (string, disposition->disposition);
337         g_mime_param_write_to_string (disposition->params, fold, string);
338         
339         header = string->str;
340         g_string_free (string, FALSE);
341         
342         buf = header + strlen ("Content-Disposition: ");
343         memmove (header, buf, strlen (buf) + 1);
344         
345         return header;
346 }