[project @ 2003-12-27 20:15:22 by bursa]

Use charset from Content-Type header.

svn path=/import/netsurf/; revision=460
This commit is contained in:
James Bursa 2003-12-27 20:15:23 +00:00
parent 01c0332607
commit ce0d5294d5
26 changed files with 169 additions and 48 deletions

View File

@ -57,7 +57,7 @@ static const struct mime_entry mime_map[] = {
/** An entry in handler_map. */
struct handler_entry {
void (*create)(struct content *c);
void (*create)(struct content *c, const char *params[]);
void (*process_data)(struct content *c, char *data, unsigned long size);
int (*convert)(struct content *c, unsigned int width, unsigned int height);
void (*revive)(struct content *c, unsigned int width, unsigned int height);
@ -169,9 +169,15 @@ struct content * content_create(char *url)
* status is changed to CONTENT_STATUS_LOADING. CONTENT_MSG_LOADING is sent to
* all users. The create function for the type is called to initialise the type
* specific parts of the content structure.
*
* \param c content structure
* \param type content_type to initialise to
* \param mime_type MIME-type string for this content
* \param params array of strings, ordered attribute, value, attribute, ..., 0
*/
void content_set_type(struct content *c, content_type type, char* mime_type)
void content_set_type(struct content *c, content_type type, char* mime_type,
const char *params[])
{
assert(c != 0);
assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN);
@ -180,7 +186,7 @@ void content_set_type(struct content *c, content_type type, char* mime_type)
c->type = type;
c->mime_type = xstrdup(mime_type);
c->status = CONTENT_STATUS_LOADING;
handler_map[type].create(c);
handler_map[type].create(c, params);
content_broadcast(c, CONTENT_MSG_LOADING, 0);
/* c may be destroyed at this point as a result of
* CONTENT_MSG_LOADING, so must not be accessed */

View File

@ -139,7 +139,8 @@ struct browser_window;
content_type content_lookup(const char *mime_type);
struct content * content_create(char *url);
void content_set_type(struct content *c, content_type type, char *mime_type);
void content_set_type(struct content *c, content_type type, char *mime_type,
const char *params[]);
void content_process_data(struct content *c, char *data, unsigned long size);
void content_convert(struct content *c, unsigned long width, unsigned long height);
void content_revive(struct content *c, unsigned long width, unsigned long height);

View File

@ -15,6 +15,8 @@
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include "netsurf/content/cache.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetchcache.h"
@ -23,7 +25,9 @@
#include "netsurf/utils/utils.h"
static regex_t re_content_type;
static void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size);
static char *fetchcache_parse_type(char *s, char **params[]);
/**
@ -95,20 +99,21 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
{
struct content *c = p;
content_type type;
char *mime_type;
char *semic;
char *url;
char *mime_type, *url;
char **params;
unsigned int i;
switch (msg) {
case FETCH_TYPE:
c->total_size = size;
mime_type = xstrdup(data);
if ((semic = strchr(mime_type, ';')) != 0)
*semic = 0; /* remove "; charset=..." */
mime_type = fetchcache_parse_type(data, &params);
type = content_lookup(mime_type);
LOG(("FETCH_TYPE, type %u", type));
content_set_type(c, type, mime_type);
content_set_type(c, type, mime_type, params);
free(mime_type);
for (i = 0; params[i]; i++)
free(params[i]);
free(params);
break;
case FETCH_DATA:
@ -172,6 +177,62 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
}
/**
* Initialise the fetchcache module.
*/
void fetchcache_init(void)
{
regcomp_wrapper(&re_content_type,
"^([-0-9a-zA-Z_.]+/[-0-9a-zA-Z_.]+)[ \t]*"
"(;[ \t]*([-0-9a-zA-Z_.]+)="
"([-0-9a-zA-Z_.]+|\"([^\"]|[\\].)*\")[ \t]*)*$",
REG_EXTENDED);
}
/**
* Parse a Content-Type header.
*
* \param s a Content-Type header
* \param params updated to point to an array of strings, ordered attribute,
* value, attribute, ..., 0
* \return a new string containing the MIME-type
*/
#define MAX_ATTRS 10
char *fetchcache_parse_type(char *s, char **params[])
{
char *type;
unsigned int i;
int r;
regmatch_t pmatch[2 + MAX_ATTRS * 3];
*params = xcalloc(MAX_ATTRS * 2 + 2, sizeof (*params)[0]);
r = regexec(&re_content_type, s, 2 + MAX_ATTRS * 3, pmatch, 0);
if (r) {
LOG(("failed to parse content-type '%s'", s));
return xstrdup(s);
}
type = strndup(s + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so);
assert(type);
/* parameters */
for (i = 0; i != MAX_ATTRS && pmatch[2 + 3 * i].rm_so != -1; i++) {
(*params)[2 * i] = strndup(s + pmatch[2 + 3 * i + 1].rm_so,
pmatch[2 + 3 * i + 1].rm_eo - pmatch[2 + 3 * i + 1].rm_so);
(*params)[2 * i + 1] = strndup(s + pmatch[2 + 3 * i + 2].rm_so,
pmatch[2 + 3 * i + 2].rm_eo - pmatch[2 + 3 * i + 2].rm_so);
assert((*params)[2 * i] && (*params)[2 * i + 1]);
}
(*params)[2 * i] = 0;
return type;
}
#ifdef TEST
#include <unistd.h>

View File

@ -26,5 +26,6 @@ struct content * fetchcache(const char *url, char *referer,
void *p1, void *p2, unsigned long width, unsigned long height,
bool only_2xx, char *post_urlenc,
struct form_successful_control *post_multipart, bool cookies);
void fetchcache_init(void);
#endif

View File

@ -17,7 +17,7 @@
#include "netsurf/utils/utils.h"
void other_create(struct content *c)
void other_create(struct content *c, char *params[])
{
c->data.other.data = xcalloc(0, 1);
c->data.other.length = 0;

View File

@ -24,7 +24,7 @@ struct content_other_data {
unsigned long length; /**< Current length of stored data. */
};
void other_create(struct content *c);
void other_create(struct content *c, char *params[]);
void other_process_data(struct content *c, char *data, unsigned long size);
int other_convert(struct content *c, unsigned int width, unsigned int height);
void other_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -91,7 +91,7 @@ const struct css_style css_blank_style = {
void css_create(struct content *c)
void css_create(struct content *c, const char *params[])
{
unsigned int i;
LOG(("content %p", c));

View File

@ -5,6 +5,21 @@
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
*/
/** \file
* CSS handling (interface).
*
* This module aims to implement CSS 2.1.
*
* CSS stylesheets are held in a struct ::content with type CONTENT_CSS.
* Creation and parsing should be carried out via the content_* functions.
*
* Styles are stored in a struct ::css_style, which can be retrieved from a
* content using css_get_style().
*
* css_parse_property_list() constructs a struct ::css_style from a CSS
* property list, as found in HTML style attributes.
*/
#ifndef _NETSURF_CSS_CSS_H_
#define _NETSURF_CSS_CSS_H_
@ -12,7 +27,7 @@
#include "libxml/HTMLparser.h"
#include "css_enum.h"
/**
/*
* structures and typedefs
*/
@ -21,6 +36,7 @@ typedef unsigned long colour; /* 0xbbggrr */
#define CSS_COLOR_INHERIT 0x2000000
#define CSS_COLOR_NONE 0x3000000
/** Representation of a CSS 2 length. */
struct css_length {
float value;
css_unit unit;
@ -36,6 +52,7 @@ typedef enum {
CSS_TEXT_DECORATION_UNKNOWN = 0x1000
} css_text_decoration;
/** Representation of a complete CSS 2 style. */
struct css_style {
colour background_color;
css_clear clear;
@ -98,19 +115,14 @@ struct css_style {
struct css_stylesheet;
struct css_selector {
const char *element;
char *class;
char *id;
};
/** Data specific to CONTENT_CSS. */
struct content_css_data {
struct css_stylesheet *css;
unsigned int import_count;
char **import_url;
struct content **import_content;
char *data;
unsigned int length;
struct css_stylesheet *css; /**< Opaque stylesheet data. */
unsigned int import_count; /**< Number of entries in import_url. */
char **import_url; /**< Imported stylesheet urls. */
struct content **import_content; /**< Imported stylesheet contents. */
char *data; /**< Source data. */
unsigned int length; /**< Current length of data. */
};
@ -191,13 +203,13 @@ struct parse_params {
#endif
/**
/*
* interface
*/
struct content;
void css_create(struct content *c);
void css_create(struct content *c, const char *params[]);
void css_process_data(struct content *c, char *data, unsigned long size);
int css_convert(struct content *c, unsigned int width, unsigned int height);
void css_revive(struct content *c, unsigned int width, unsigned int height);
@ -218,7 +230,7 @@ void css_add_declarations(struct css_style *style, struct css_node *declaration)
unsigned int css_hash(const char *s);
void css_parser_Trace(FILE *TraceFILE, char *zTracePrompt);
void *css_parser_Alloc(void *(*mallocProc)(int));
void *css_parser_alloc(void *(*mallocProc)(size_t));
void css_parser_Free(void *p, void (*freeProc)(void*));
void css_parser_(void *yyp, int yymajor, char* yyminor,
struct parse_params *param);

View File

@ -39,6 +39,7 @@ int main(int argc, char *argv[])
fetch_init();
cache_init();
fetchcache_init();
while (1) {
puts("=== URL:");
@ -46,7 +47,7 @@ int main(int argc, char *argv[])
return 0;
url[strlen(url) - 1] = 0;
destroyed = 0;
c = fetchcache(url, 0, callback, 0, 0, 100, 1000, false, 0, 0);
c = fetchcache(url, 0, callback, 0, 0, 100, 1000, false, 0, 0, true);
if (c) {
done = c->status == CONTENT_STATUS_DONE;
while (!done)

View File

@ -52,6 +52,7 @@ void netsurf_init(int argc, char** argv)
gui_init(argc, argv);
fetch_init();
cache_init();
fetchcache_init();
nspng_init();
nsgif_init();
}

View File

@ -29,9 +29,21 @@ static void html_object_callback(content_msg msg, struct content *object,
void *p1, void *p2, const char *error);
void html_create(struct content *c)
void html_create(struct content *c, const char *params[])
{
c->data.html.parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0, XML_CHAR_ENCODING_8859_1);
unsigned int i;
xmlCharEncoding encoding = XML_CHAR_ENCODING_8859_1;
for (i = 0; params[i]; i += 2) {
if (strcasecmp(params[i], "charset") == 0) {
encoding = xmlParseCharEncoding(params[i + 1]);
if (encoding == XML_CHAR_ENCODING_ERROR)
encoding = XML_CHAR_ENCODING_8859_1;
break;
}
}
c->data.html.parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0, encoding);
c->data.html.layout = NULL;
c->data.html.style = NULL;
c->data.html.fonts = NULL;
@ -341,9 +353,10 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* create stylesheet */
LOG(("style element"));
if (c->data.html.stylesheet_content[1] == 0) {
const char *params[] = { 0 };
c->data.html.stylesheet_content[1] =
content_create(c->data.html.base_url);
content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS, "text/css");
content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS, "text/css", params);
}
/* can't just use xmlNodeGetContent(node), because that won't give

View File

@ -51,7 +51,7 @@ struct content_html_data {
} *object;
};
void html_create(struct content *c);
void html_create(struct content *c, const char *params[]);
void html_process_data(struct content *c, char *data, unsigned long size);
int html_convert(struct content *c, unsigned int width, unsigned int height);
void html_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -18,9 +18,9 @@ static const char header[] = "<html><body><pre>";
static const char footer[] = "</pre></body></html>";
void textplain_create(struct content *c)
void textplain_create(struct content *c, const char *params[])
{
html_create(c);
html_create(c, params);
htmlParseChunk(c->data.html.parser, header, sizeof(header) - 1, 0);
}

View File

@ -10,7 +10,7 @@
#include "netsurf/content/content.h"
void textplain_create(struct content *c);
void textplain_create(struct content *c, const char *params[]);
void textplain_process_data(struct content *c, char *data, unsigned long size);
int textplain_convert(struct content *c, unsigned int width, unsigned int height);
void textplain_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -14,7 +14,7 @@
#include "netsurf/utils/log.h"
#include "oslib/drawfile.h"
void draw_create(struct content *c)
void draw_create(struct content *c, const char *params[])
{
c->data.draw.data = xcalloc(0, 1);
c->data.draw.length = 0;

View File

@ -16,7 +16,7 @@ struct content_draw_data {
};
void draw_init(void);
void draw_create(struct content *c);
void draw_create(struct content *c, const char *params[]);
void draw_process_data(struct content *c, char *data, unsigned long size);
int draw_convert(struct content *c, unsigned int width, unsigned int height);
void draw_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -26,7 +26,7 @@ void nsgif_init(void)
{
}
void nsgif_create(struct content*c)
void nsgif_create(struct content *c, const char *params[])
{
c->data.gif.sprite_area = 0;
c->data.gif.data = xcalloc(0, 1);

View File

@ -21,7 +21,7 @@ struct content_gif_data {
};
void nsgif_init(void);
void nsgif_create(struct content *c);
void nsgif_create(struct content *c, const char *params[]);
void nsgif_process_data(struct content *c, char *data, unsigned long size);
int nsgif_convert(struct content *c, unsigned int width, unsigned int height);
void nsgif_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -19,7 +19,7 @@
#include "oslib/jpeg.h"
void jpeg_create(struct content *c)
void jpeg_create(struct content *c, const char *params[])
{
c->data.jpeg.data = xcalloc(0, 1);
c->data.jpeg.length = 0;

View File

@ -15,7 +15,7 @@ struct content_jpeg_data {
unsigned long length;
};
void jpeg_create(struct content *c);
void jpeg_create(struct content *c, const char *params[]);
void jpeg_process_data(struct content *c, char *data, unsigned long size);
int jpeg_convert(struct content *c, unsigned int width, unsigned int height);
void jpeg_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -64,7 +64,7 @@ void nspng_init(void)
}
void nspng_create(struct content *c)
void nspng_create(struct content *c, const char *params[])
{
#ifndef NO_IFC
if (imagefileconvert) {

View File

@ -27,7 +27,7 @@ struct content_png_data {
};
void nspng_init(void);
void nspng_create(struct content *c);
void nspng_create(struct content *c, const char *params[]);
void nspng_process_data(struct content *c, char *data, unsigned long size);
int nspng_convert(struct content *c, unsigned int width, unsigned int height);
void nspng_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -15,7 +15,7 @@
#include "oslib/colourtrans.h"
#include "oslib/osspriteop.h"
void sprite_create(struct content *c)
void sprite_create(struct content *c, const char *params[])
{
c->data.sprite.data = xcalloc(4, 1);
c->data.sprite.length = 4;

View File

@ -18,7 +18,7 @@ struct content_sprite_data {
};
void sprite_init(void);
void sprite_create(struct content *c);
void sprite_create(struct content *c, const char *params[]);
void sprite_process_data(struct content *c, char *data, unsigned long size);
int sprite_convert(struct content *c, unsigned int width, unsigned int height);
void sprite_revive(struct content *c, unsigned int width, unsigned int height);

View File

@ -13,6 +13,8 @@
#include <string.h>
#include <sys/stat.h>
#include <uri.h>
#include <sys/types.h>
#include <regex.h>
#include "libxml/encoding.h"
#include "libxml/uri.h"
#include "netsurf/utils/log.h"
@ -256,3 +258,23 @@ bool is_dir(const char *path)
return S_ISDIR(s.st_mode) ? true : false;
}
/**
* Compile a regular expression, handling errors.
*
* Parameters as for regcomp(), see man regex.
*/
void regcomp_wrapper(regex_t *preg, const char *regex, int cflags)
{
char errbuf[200];
int r;
r = regcomp(preg, regex, cflags);
if (r) {
regerror(r, preg, errbuf, sizeof errbuf);
fprintf(stderr, "Failed to compile regexp '%s'\n", regex);
die(errbuf);
}
}

View File

@ -10,6 +10,8 @@
#include <stdbool.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include "libxml/encoding.h"
void die(const char * const error);
@ -27,5 +29,6 @@ char *squash_tolat1(xmlChar *s);
char *url_join(char *rel_url, char *base_url);
char *get_host_from_url(char* url);
bool is_dir(const char *path);
void regcomp_wrapper(regex_t *preg, const char *regex, int cflags);
#endif