1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2000-2012 Jeffrey Stedfast
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.
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.
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
30 #include "gmime-common.h"
31 #include "gmime-content-type.h"
32 #include "gmime-parse-utils.h"
33 #include "gmime-events.h"
36 #ifdef ENABLE_WARNINGS
40 #endif /* ENABLE_WARNINGS */
46 * SECTION: gmime-content-type
47 * @title: GMimeContentType
48 * @short_description: Content-Type fields
51 * A #GMimeContentType represents the pre-parsed contents of a
52 * Content-Type header field.
56 static void g_mime_content_type_class_init (GMimeContentTypeClass *klass);
57 static void g_mime_content_type_init (GMimeContentType *content_type, GMimeContentTypeClass *klass);
58 static void g_mime_content_type_finalize (GObject *object);
61 static GObjectClass *parent_class = NULL;
65 g_mime_content_type_get_type (void)
67 static GType type = 0;
70 static const GTypeInfo info = {
71 sizeof (GMimeContentTypeClass),
72 NULL, /* base_class_init */
73 NULL, /* base_class_finalize */
74 (GClassInitFunc) g_mime_content_type_class_init,
75 NULL, /* class_finalize */
76 NULL, /* class_data */
77 sizeof (GMimeContentType),
79 (GInstanceInitFunc) g_mime_content_type_init,
82 type = g_type_register_static (G_TYPE_OBJECT, "GMimeContentType", &info, 0);
90 g_mime_content_type_class_init (GMimeContentTypeClass *klass)
92 GObjectClass *object_class = G_OBJECT_CLASS (klass);
94 parent_class = g_type_class_ref (G_TYPE_OBJECT);
96 object_class->finalize = g_mime_content_type_finalize;
100 g_mime_content_type_init (GMimeContentType *content_type, GMimeContentTypeClass *klass)
102 content_type->param_hash = g_hash_table_new (g_mime_strcase_hash, g_mime_strcase_equal);
103 content_type->priv = g_mime_event_new ((GObject *) content_type);
104 content_type->params = NULL;
105 content_type->subtype = NULL;
106 content_type->type = NULL;
110 g_mime_content_type_finalize (GObject *object)
112 GMimeContentType *content_type = (GMimeContentType *) object;
114 g_hash_table_destroy (content_type->param_hash);
115 g_mime_param_destroy (content_type->params);
116 g_mime_event_destroy (content_type->priv);
117 g_free (content_type->subtype);
118 g_free (content_type->type);
120 G_OBJECT_CLASS (parent_class)->finalize (object);
125 * g_mime_content_type_new:
126 * @type: MIME type (or %NULL for "text")
127 * @subtype: MIME subtype (or %NULL for "plain")
129 * Creates a Content-Type object with type @type and subtype @subtype.
131 * Returns: a new #GMimeContentType object.
134 g_mime_content_type_new (const char *type, const char *subtype)
136 GMimeContentType *mime_type;
138 mime_type = g_object_newv (GMIME_TYPE_CONTENT_TYPE, 0, NULL);
140 if (type && *type && subtype && *subtype) {
141 mime_type->type = g_strdup (type);
142 mime_type->subtype = g_strdup (subtype);
145 mime_type->type = g_strdup (type);
146 if (!g_ascii_strcasecmp (type, "text")) {
147 mime_type->subtype = g_strdup ("plain");
148 } else if (!g_ascii_strcasecmp (type, "multipart")) {
149 mime_type->subtype = g_strdup ("mixed");
151 g_free (mime_type->type);
152 mime_type->type = g_strdup ("application");
153 mime_type->subtype = g_strdup ("octet-stream");
156 mime_type->type = g_strdup ("application");
157 mime_type->subtype = g_strdup ("octet-stream");
160 w(g_warning ("Invalid or incomplete type: %s%s%s: defaulting to %s/%s",
161 type ? type : "", subtype ? "/" : "", subtype ? subtype : "",
162 mime_type->type, mime_type->subtype));
170 * g_mime_content_type_new_from_string:
171 * @str: input string containing a content-type (and params)
173 * Constructs a new Content-Type object based on the input string.
175 * Returns: a new #GMimeContentType object based on the input string.
178 g_mime_content_type_new_from_string (const char *str)
180 GMimeContentType *mime_type;
181 const char *inptr = str;
182 char *type, *subtype;
184 g_return_val_if_fail (str != NULL, NULL);
186 if (!g_mime_parse_content_type (&inptr, &type, &subtype))
187 return g_mime_content_type_new ("application", "octet-stream");
189 mime_type = g_object_newv (GMIME_TYPE_CONTENT_TYPE, 0, NULL);
190 mime_type->subtype = subtype;
191 mime_type->type = type;
193 /* skip past any remaining junk that shouldn't be here... */
194 decode_lwsp (&inptr);
195 while (*inptr && *inptr != ';')
198 if (*inptr++ == ';' && *inptr) {
201 param = mime_type->params = g_mime_param_new_from_string (inptr);
202 while (param != NULL) {
203 g_hash_table_insert (mime_type->param_hash, param->name, param);
213 * g_mime_content_type_to_string:
214 * @mime_type: a #GMimeContentType object
216 * Allocates a string buffer containing the type and subtype defined
219 * Returns: an allocated string containing the type and subtype of the
220 * content-type in the format: type/subtype.
223 g_mime_content_type_to_string (GMimeContentType *mime_type)
227 g_return_val_if_fail (GMIME_IS_CONTENT_TYPE (mime_type), NULL);
229 /* type and subtype should never be NULL, but check anyway */
230 string = g_strdup_printf ("%s/%s", mime_type->type ? mime_type->type : "text",
231 mime_type->subtype ? mime_type->subtype : "plain");
238 * g_mime_content_type_is_type:
239 * @mime_type: a #GMimeContentType object
240 * @type: MIME type to compare against
241 * @subtype: MIME subtype to compare against
243 * Compares the given type and subtype with that of the given mime
246 * Returns: TRUE if the MIME types match or FALSE otherwise. You may
247 * use "*" in place of @type and/or @subtype as a wilcard.
250 g_mime_content_type_is_type (GMimeContentType *mime_type, const char *type, const char *subtype)
252 g_return_val_if_fail (GMIME_IS_CONTENT_TYPE (mime_type), FALSE);
253 g_return_val_if_fail (mime_type->type != NULL, FALSE);
254 g_return_val_if_fail (mime_type->subtype != NULL, FALSE);
255 g_return_val_if_fail (type != NULL, FALSE);
256 g_return_val_if_fail (subtype != NULL, FALSE);
258 if (!strcmp (type, "*") || !g_ascii_strcasecmp (mime_type->type, type)) {
259 if (!strcmp (subtype, "*")) {
264 if (!g_ascii_strcasecmp (mime_type->subtype, subtype))
273 * g_mime_content_type_set_media_type:
274 * @mime_type: a #GMimeContentType object
277 * Sets the Content-Type's media type.
280 g_mime_content_type_set_media_type (GMimeContentType *mime_type, const char *type)
284 g_return_if_fail (GMIME_IS_CONTENT_TYPE (mime_type));
285 g_return_if_fail (type != NULL);
287 buf = g_strdup (type);
288 g_free (mime_type->type);
289 mime_type->type = buf;
291 g_mime_event_emit (mime_type->priv, NULL);
296 * g_mime_content_type_get_media_type:
297 * @mime_type: a #GMimeContentType object
299 * Gets the Content-Type's media type.
301 * Returns: the Content-Type's media type.
304 g_mime_content_type_get_media_type (GMimeContentType *mime_type)
306 g_return_val_if_fail (GMIME_IS_CONTENT_TYPE (mime_type), NULL);
308 return mime_type->type;
313 * g_mime_content_type_set_media_subtype:
314 * @mime_type: a #GMimeContentType object
315 * @subtype: media subtype
317 * Sets the Content-Type's media subtype.
320 g_mime_content_type_set_media_subtype (GMimeContentType *mime_type, const char *subtype)
324 g_return_if_fail (GMIME_IS_CONTENT_TYPE (mime_type));
325 g_return_if_fail (subtype != NULL);
327 buf = g_strdup (subtype);
328 g_free (mime_type->subtype);
329 mime_type->subtype = buf;
331 g_mime_event_emit (mime_type->priv, NULL);
336 * g_mime_content_type_get_media_subtype:
337 * @mime_type: a #GMimeContentType object
339 * Gets the Content-Type's media sub-type.
341 * Returns: the Content-Type's media sub-type.
344 g_mime_content_type_get_media_subtype (GMimeContentType *mime_type)
346 g_return_val_if_fail (GMIME_IS_CONTENT_TYPE (mime_type), NULL);
348 return mime_type->subtype;
353 * g_mime_content_type_set_params:
354 * @mime_type: a #GMimeContentType object
355 * @params: a list of #GMimeParam objects
357 * Sets the Content-Type's parameter list.
360 g_mime_content_type_set_params (GMimeContentType *mime_type, GMimeParam *params)
362 g_return_if_fail (GMIME_IS_CONTENT_TYPE (mime_type));
364 /* clear the current list/hash */
365 g_hash_table_remove_all (mime_type->param_hash);
366 g_mime_param_destroy (mime_type->params);
367 mime_type->params = params;
369 while (params != NULL) {
370 g_hash_table_insert (mime_type->param_hash, params->name, params);
371 params = params->next;
374 g_mime_event_emit (mime_type->priv, NULL);
379 * g_mime_content_type_get_params:
380 * @mime_type: a #GMimeContentType object
382 * Gets the Content-Type's parameter list.
384 * Returns: the Content-Type's parameter list.
387 g_mime_content_type_get_params (GMimeContentType *mime_type)
389 g_return_val_if_fail (GMIME_IS_CONTENT_TYPE (mime_type), NULL);
391 return mime_type->params;
396 * g_mime_content_type_set_parameter:
397 * @mime_type: MIME Content-Type
398 * @attribute: parameter name (aka attribute)
399 * @value: parameter value
401 * Sets a parameter on the Content-Type.
404 g_mime_content_type_set_parameter (GMimeContentType *mime_type, const char *attribute, const char *value)
406 GMimeParam *param = NULL;
408 g_return_if_fail (GMIME_IS_CONTENT_TYPE (mime_type));
409 g_return_if_fail (attribute != NULL);
410 g_return_if_fail (value != NULL);
412 if ((param = g_hash_table_lookup (mime_type->param_hash, attribute))) {
413 g_free (param->value);
414 param->value = g_strdup (value);
416 param = g_mime_param_new (attribute, value);
417 mime_type->params = g_mime_param_append_param (mime_type->params, param);
418 g_hash_table_insert (mime_type->param_hash, param->name, param);
421 g_mime_event_emit (mime_type->priv, NULL);
426 * g_mime_content_type_get_parameter:
427 * @mime_type: a #GMimeContentType object
428 * @attribute: parameter name (aka attribute)
430 * Gets the parameter value specified by @attribute if it's available.
432 * Returns: a const pointer to the paramer value specified by
433 * @attribute or %NULL on fail.
436 g_mime_content_type_get_parameter (GMimeContentType *mime_type, const char *attribute)
440 g_return_val_if_fail (GMIME_IS_CONTENT_TYPE (mime_type), NULL);
441 g_return_val_if_fail (attribute != NULL, NULL);
443 if (!(param = g_hash_table_lookup (mime_type->param_hash, attribute)))