NetSurf
content_factory.c
Go to the documentation of this file.
1/*
2 * Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * Content factory implementation
22 */
23
24#include <assert.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include "utils/http.h"
29
30#include "content/content.h"
33#include "content/llcache.h"
34
35/**
36 * Entry in list of content handlers
37 */
38typedef struct content_handler_entry {
39 /** Next entry */
41
42 /** MIME type handled by handler */
43 lwc_string *mime_type;
44 /** Content handler object */
47
49
50/**
51 * Clean up after the content factory
52 */
54{
56
57 while (content_handlers != NULL) {
58 victim = content_handlers;
59
61
62 if (victim->handler->fini != NULL)
63 victim->handler->fini();
64
65 lwc_string_unref(victim->mime_type);
66
67 free(victim);
68 }
69}
70
71/**
72 * Register a handler with the content factory
73 *
74 * \param mime_type MIME type to handle
75 * \param handler Content handler for MIME type
76 * \return NSERROR_OK on success, appropriate error otherwise
77 *
78 * \note Latest registration for a MIME type wins
79 */
82{
83 lwc_string *imime_type;
84 lwc_error lerror;
86 bool match;
87
88 lerror = lwc_intern_string(mime_type, strlen(mime_type), &imime_type);
89 if (lerror != lwc_error_ok)
90 return NSERROR_NOMEM;
91
92 for (entry = content_handlers; entry != NULL; entry = entry->next) {
93 if (lwc_string_caseless_isequal(imime_type, entry->mime_type,
94 &match) == lwc_error_ok && match)
95 break;
96 }
97
98 if (entry == NULL) {
99 entry = malloc(sizeof(content_handler_entry));
100 if (entry == NULL)
101 return NSERROR_NOMEM;
102
103 entry->next = content_handlers;
104 content_handlers = entry;
105
106 entry->mime_type = imime_type;
107 } else {
108 lwc_string_unref(imime_type);
109 }
110
111 entry->handler = handler;
112
113 return NSERROR_OK;
114}
115
116/**
117 * Find a handler for a MIME type.
118 *
119 * \param mime_type MIME type to search for
120 * \return Associated handler, or NULL if none
121 */
122static const content_handler *content_lookup(lwc_string *mime_type)
123{
125 bool match;
126
127 for (entry = content_handlers; entry != NULL; entry = entry->next) {
128 if (lwc_string_caseless_isequal(mime_type, entry->mime_type,
129 &match) == lwc_error_ok && match) {
130 break;
131 }
132 }
133
134 if (entry != NULL) {
135 return entry->handler;
136 }
137
138 return NULL;
139}
140
141/**
142 * Compute the generic content type for a MIME type
143 *
144 * \param mime_type MIME type to consider
145 * \return Generic content type
146 */
148{
151
153 if (handler != NULL) {
154 type = handler->type();
155 }
156
157 return type;
158}
159
160/**
161 * Create a content object
162 *
163 * \param llcache Underlying source data handle
164 * \param fallback_charset Character set to fall back to if none specified
165 * \param quirks Quirkiness of containing document
166 * \param effective_type Effective MIME type of content
167 * \return Pointer to content object, or NULL on failure
168 */
170 const char *fallback_charset, bool quirks,
171 lwc_string *effective_type)
172{
173 struct content *c;
174 const char *content_type_header;
176 http_content_type *ct = NULL;
177 nserror error;
178
179 handler = content_lookup(effective_type);
180 if (handler == NULL)
181 return NULL;
182
183 assert(handler->create != NULL);
184
185 /* Use the parameters from the declared Content-Type header */
186 content_type_header =
187 llcache_handle_get_header(llcache, "Content-Type");
188 if (content_type_header != NULL) {
189 /* We don't care if this fails */
190 http_parse_content_type(content_type_header, &ct);
191 }
192
193 error = handler->create(handler, effective_type,
194 ct != NULL ? ct->parameters : NULL,
196 &c);
197
198 if (ct != NULL)
200
201 if (error != NSERROR_OK)
202 return NULL;
203
204 return c;
205}
206
nserror http_parse_content_type(const char *header_value, http_content_type **result)
Parse an HTTP Content-Type header value.
Definition: content-type.c:30
void http_content_type_destroy(http_content_type *victim)
Destroy a content type object.
Definition: content-type.c:122
Content handling interface.
struct content_handler_entry content_handler_entry
Entry in list of content handlers.
static const content_handler * content_lookup(lwc_string *mime_type)
Find a handler for a MIME type.
nserror content_factory_register_handler(const char *mime_type, const content_handler *handler)
Register a handler with the content factory.
content_type content_factory_type_from_mime_type(lwc_string *mime_type)
Compute the generic content type for a MIME type.
struct content * content_factory_create_content(llcache_handle *llcache, const char *fallback_charset, bool quirks, lwc_string *effective_type)
Create a content object.
void content_factory_fini(void)
Clean up after the content factory.
static content_handler_entry * content_handlers
Protected interface to Content handling.
content_type
The type of a content.
Definition: content_type.h:53
@ CONTENT_NONE
no type for content
Definition: content_type.h:55
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
const char * type
Definition: filetype.cpp:44
HTTP header parsing functions.
static struct llcache_s * llcache
low level cache state
Definition: llcache.c:267
const char * llcache_handle_get_header(const llcache_handle *handle, const char *key)
Retrieve a header value associated with a low-level cache object.
Definition: llcache.c:4210
Low-level resource cache (interface)
Interface to utility string handling.
Entry in list of content handlers.
lwc_string * mime_type
MIME type handled by handler.
struct content_handler_entry * next
Next entry.
const content_handler * handler
Content handler object.
Content operation function table.
nserror(* create)(const struct content_handler *handler, lwc_string *imime_type, const struct http_parameter *params, struct llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c)
content_type(* type)(void)
void(* fini)(void)
Content which corresponds to a single URL.
bool quirks
Content is in quirks mode.
char * fallback_charset
Fallback charset, or NULL.
const struct content_handler * handler
Handler for content.
http_parameter * parameters
Definition: content-type.h:28
Handle to low-level cache object.
Definition: llcache.c:76