mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 20:16:54 +03:00
[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:
parent
01c0332607
commit
ce0d5294d5
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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, ¶ms);
|
||||
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>
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
44
css/css.h
44
css/css.h
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user