From 9fa8f4037af0f35e690fda48c16f9896c058a029 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 7 Sep 2003 21:08:13 +0000 Subject: [PATCH] [project @ 2003-09-07 21:08:13 by bursa] Document cache and content, split struct content up. svn path=/import/netsurf/; revision=270 --- content/cache.c | 55 ++++++++++--- content/cache.h | 23 ++---- content/content.c | 96 ++++++++++++++++++---- content/content.h | 205 ++++++++++++++++------------------------------ content/other.c | 1 + content/other.h | 7 +- css/css.h | 7 ++ render/html.h | 42 +++++++++- riscos/gif.h | 12 ++- riscos/jpeg.h | 7 +- riscos/plugin.h | 14 +++- riscos/png.h | 15 +++- 12 files changed, 302 insertions(+), 182 deletions(-) diff --git a/content/cache.c b/content/cache.c index 033c65909..7fab30352 100644 --- a/content/cache.c +++ b/content/cache.c @@ -5,6 +5,20 @@ * Copyright 2003 James Bursa */ +/** \file + * Caching of converted contents (implementation). + * + * The current implementation is a memory cache only. The content structures + * are stored in two linked lists. + * - inuse_list contains non-freeable contents + * - unused_list contains freeable contents + * + * The cache has a suggested maximum size. If the sum of the size attribute of + * the contents exceeds the maximum, contents from the freeable list are + * destroyed until the size drops below the maximum, if possible. Freeing is + * attempted only when cache_put is used. + */ + #include #include #include @@ -26,7 +40,7 @@ void content_destroy(struct content *c); #endif -/** +/* * internal structures and declarations */ @@ -46,11 +60,16 @@ static struct cache_entry unused_list_sentinel = {0, &unused_list_sentinel, &unu static struct cache_entry *inuse_list = &inuse_list_sentinel; static struct cache_entry *unused_list = &unused_list_sentinel; +/** Suggested maximum size of cache (bytes). */ static unsigned long max_size = 1024*1024; /* TODO: make this configurable */ /** - * cache_init -- initialise the cache manager + * Initialise the cache manager. + * + * Must be called before using any other cache functions. + * + * Currently does nothing. */ void cache_init(void) @@ -59,7 +78,11 @@ void cache_init(void) /** - * cache_quit -- terminate the cache manager + * Terminate the cache manager. + * + * Must be called before the program exits. + * + * Currently does nothing. */ void cache_quit(void) @@ -68,7 +91,10 @@ void cache_quit(void) /** - * cache_get -- retrieve url from memory cache or disc cache + * Retrieve a content from the memory cache or disc cache. + * + * Returns the content and sets it to non-freeable on success. Returns 0 if + * the URL is not present in the cache. */ struct content * cache_get(const char * const url) @@ -107,7 +133,9 @@ struct content * cache_get(const char * const url) /** - * cache_put -- place content in the memory cache + * Add a content to the memory cache. + * + * The content is set to non-freeable. */ void cache_put(struct content * content) @@ -129,7 +157,9 @@ void cache_put(struct content * content) /** - * cache_freeable -- inform cache that the content has no users + * Inform cache that the content has no users. + * + * The content is set to freeable, and may be destroyed in the future. */ void cache_freeable(struct content * content) @@ -150,7 +180,12 @@ void cache_freeable(struct content * content) /** - * cache_destroy -- remove a content immediately + * Remove a content from the cache immediately. + * + * Informs the cache that a content is about to be destroyed, and must be + * removed from the cache. This should be called when an error occurs when + * loading an url and the content is destroyed. The content must be + * non-freeable. */ void cache_destroy(struct content * content) @@ -163,7 +198,7 @@ void cache_destroy(struct content * content) /** - * cache_shrink -- attempt to reduce cache size below max_size + * Attempt to reduce cache size below max_size. */ void cache_shrink(void) @@ -187,7 +222,7 @@ void cache_shrink(void) /** - * cache_size -- current size of the cache + * Return current size of the cache. */ unsigned long cache_size(void) @@ -203,7 +238,7 @@ unsigned long cache_size(void) /** - * cache_dump -- dump contents of cache + * Dump contents of cache. */ void cache_dump(void) { diff --git a/content/cache.h b/content/cache.h index 4bc64d6e3..8cdb9b63c 100644 --- a/content/cache.h +++ b/content/cache.h @@ -5,27 +5,18 @@ * Copyright 2003 James Bursa */ -/** - * The cache contains a content structure for each url. If a structure is not +/** \file + * Caching of converted contents (interface). + * + * The cache contains a ::content structure for each url. If a structure is not * in state CONTENT_STATUS_DONE, then loading and converting must be actively * in progress, so that when a not done content is retrieved no action needs * to be taken to load it. * - * Each content in the cache is either freeable or not freeable. If an entry - * is freeable, the cache may destroy it through content_destroy at any time. + * Each content in the cache is either freeable or non-freeable. If an entry + * is freeable, the cache may destroy it through content_destroy() at any time. * - * cache_get attempts to retrieve an url from the cache, returning the - * content and setting it to not freeable on success, and returning 0 on - * failure. - * - * cache_put adds a content to the cache, setting it to not freeable. - * - * cache_freeable sets the content to freeable. - * - * cache_destroy informs the cache that a content is about to be destroyed, - * and must be removed from the cache. This should be called when an error - * occurs when loading an url and the content is destroyed. The content must - * be non freeable. + * The cache uses the cache element of struct content. */ #ifndef _NETSURF_DESKTOP_CACHE_H_ diff --git a/content/content.c b/content/content.c index b4bb72476..df8c6dd78 100644 --- a/content/content.c +++ b/content/content.c @@ -5,6 +5,13 @@ * Copyright 2003 James Bursa */ +/** \file + * Content handling (implementation). + * + * This implementation is based on the ::handler_map array, which maps + * ::content_type to the functions which implement that type. + */ + #include #include #include @@ -23,11 +30,12 @@ #include "netsurf/utils/utils.h" -/* mime_map must be in sorted order by mime_type */ +/** An entry in mime_map. */ struct mime_entry { char mime_type[40]; content_type type; }; +/** A map from MIME type to ::content_type. Must be sorted by mime_type. */ static const struct mime_entry mime_map[] = { #ifdef riscos {"image/gif", CONTENT_GIF}, @@ -40,7 +48,7 @@ static const struct mime_entry mime_map[] = { }; #define MIME_MAP_COUNT (sizeof(mime_map) / sizeof(mime_map[0])) -/* handler_map must be ordered as enum content_type */ +/** An entry in handler_map. */ struct handler_entry { void (*create)(struct content *c); void (*process_data)(struct content *c, char *data, unsigned long size); @@ -60,6 +68,8 @@ struct handler_entry { struct content *page, struct box *box, struct object_params *params, void **state); }; +/** A table of handler functions, indexed by ::content_type. + * Must be ordered as enum ::content_type. */ static const struct handler_entry handler_map[] = { {html_create, html_process_data, html_convert, html_revive, html_reformat, html_destroy, html_redraw, @@ -89,7 +99,9 @@ static const struct handler_entry handler_map[] = { /** - * content_lookup -- look up mime type + * Convert a MIME type to a content_type. + * + * The returned ::content_type will always be suitable for content_set_type(). */ content_type content_lookup(const char *mime_type) @@ -109,7 +121,10 @@ content_type content_lookup(const char *mime_type) /** - * content_create -- create a content structure + * Create a new content structure. + * + * The type is initialised to CONTENT_UNKNOWN, and the status to + * CONTENT_STATUS_TYPE_UNKNOWN. */ struct content * content_create(char *url) @@ -124,6 +139,7 @@ struct content * content_create(char *url) c->cache = 0; c->size = sizeof(struct content); c->fetch = 0; + c->mime_type = 0; strcpy(c->status_message, "Loading"); user_sentinel = xcalloc(1, sizeof(*user_sentinel)); user_sentinel->callback = 0; @@ -135,7 +151,12 @@ struct content * content_create(char *url) /** - * content_set_type -- initialise the content for the specified mime type + * Initialise the content for the specified type. + * + * The type is updated to the given type, and a copy of mime_type is taken. The + * 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. */ void content_set_type(struct content *c, content_type type, char* mime_type) @@ -153,7 +174,9 @@ void content_set_type(struct content *c, content_type type, char* mime_type) /** - * content_process_data -- process a block source data + * Process a block of source data. + * + * Calls the process_data function for the content. */ void content_process_data(struct content *c, char *data, unsigned long size) @@ -166,7 +189,17 @@ void content_process_data(struct content *c, char *data, unsigned long size) /** - * content_convert -- all data has arrived, complete the conversion + * All data has arrived, convert for display. + * + * Calls the convert function for the content. + * + * - If the conversion succeeds, but there is still some processing required + * (eg. loading images), the content gets status CONTENT_STATUS_READY, and a + * CONTENT_MSG_READY is sent to all users. + * - If the conversion succeeds and is complete, the content gets status + * CONTENT_STATUS_DONE, and CONTENT_MSG_DONE is sent. + * - If the conversion fails, CONTENT_MSG_ERROR is sent. The content is then + * destroyed and must no longer be used. */ void content_convert(struct content *c, unsigned long width, unsigned long height) @@ -194,8 +227,10 @@ void content_convert(struct content *c, unsigned long width, unsigned long heigh /** - * content_revive -- fix content that has been loaded from the cache - * eg. load dependencies, reformat to current width + * Fix content that has been loaded from the cache. + * + * Calls the revive function for the content. The content will be processed for + * display, for example dependencies loaded or reformated to current width. */ void content_revive(struct content *c, unsigned long width, unsigned long height) @@ -209,7 +244,9 @@ void content_revive(struct content *c, unsigned long width, unsigned long height /** - * content_reformat -- reformat to new size + * Reformat to new size. + * + * Calls the reformat function for the content. */ void content_reformat(struct content *c, unsigned long width, unsigned long height) @@ -223,7 +260,9 @@ void content_reformat(struct content *c, unsigned long width, unsigned long heig /** - * content_destroy -- free content + * Destroy and free a content. + * + * Calls the destroy function for the content, and frees the structure. */ void content_destroy(struct content *c) @@ -237,12 +276,15 @@ void content_destroy(struct content *c) next = user->next; xfree(user); } + free(c->mime_type); xfree(c); } /** - * content_redraw -- display content on screen + * Display content on screen. + * + * Calls the redraw function for the content, if it exists. */ void content_redraw(struct content *c, long x, long y, @@ -255,7 +297,10 @@ void content_redraw(struct content *c, long x, long y, /** - * content_add_user -- register a user for callbacks + * Register a user for callbacks. + * + * The callback will be called with p1 and p2 when content_broadcast() is + * called with the content. */ void content_add_user(struct content *c, @@ -275,7 +320,10 @@ void content_add_user(struct content *c, /** - * content_remove_user -- remove a callback user + * Remove a callback user. + * + * The callback function, p1, and p2 must be identical to those passed to + * content_add_user(). */ void content_remove_user(struct content *c, @@ -320,7 +368,7 @@ void content_remove_user(struct content *c, /** - * content_broadcast -- send a message to all users + * Send a message to all users. */ void content_broadcast(struct content *c, content_msg msg, char *error) @@ -335,6 +383,12 @@ void content_broadcast(struct content *c, content_msg msg, char *error) } +/** + * Add an instance to a content. + * + * Calls the add_instance function for the content. + */ + void content_add_instance(struct content *c, struct browser_window *bw, struct content *page, struct box *box, struct object_params *params, void **state) @@ -347,6 +401,12 @@ void content_add_instance(struct content *c, struct browser_window *bw, } +/** + * Remove an instance from a content. + * + * Calls the remove_instance function for the content. + */ + void content_remove_instance(struct content *c, struct browser_window *bw, struct content *page, struct box *box, struct object_params *params, void **state) @@ -359,6 +419,12 @@ void content_remove_instance(struct content *c, struct browser_window *bw, } +/** + * Reshape an instance of a content. + * + * Calls the reshape_instance function for the content. + */ + void content_reshape_instance(struct content *c, struct browser_window *bw, struct content *page, struct box *box, struct object_params *params, void **state) diff --git a/content/content.h b/content/content.h index 77031f077..a73fff1ef 100644 --- a/content/content.h +++ b/content/content.h @@ -6,35 +6,42 @@ * Copyright 2003 Philip Pemberton */ +/** \file + * Content handling (interface). + * + * The content functions manipulate struct contents, which correspond to URLs. + * + * Each content has a type. The type is used to call a specific implementation + * of functions such as content_process_data(). + * + * Contents have an associated set of users, which are informed by a callback + * when the state of the content changes or something interesting happens. + * + * Optionally, contents may have instances (depending on type). Instances + * represent copies of the same URL, for example if a page is open in two + * windows, or a page contains the same image twice. + */ + #ifndef _NETSURF_DESKTOP_CONTENT_H_ #define _NETSURF_DESKTOP_CONTENT_H_ #include "libxml/HTMLparser.h" -#ifdef riscos -#include "libpng/png.h" -#include "oslib/osspriteop.h" -#endif #include "netsurf/content/cache.h" #include "netsurf/content/fetch.h" +#include "netsurf/content/other.h" #include "netsurf/css/css.h" #include "netsurf/render/box.h" #include "netsurf/render/font.h" +#include "netsurf/render/html.h" +#ifdef riscos +#include "netsurf/riscos/gif.h" +#include "netsurf/riscos/jpeg.h" +#include "netsurf/riscos/plugin.h" +#include "netsurf/riscos/png.h" +#endif -/** - * A struct content corresponds to a single url. - * - * It is in one of the following states: - * CONTENT_FETCHING - the data is being fetched and/or converted - * for use by the browser - * CONTENT_READY - the content has been processed and is ready - * to display - * - * The converted data is stored in the cache, not the source data. - * Users of the structure are counted in use_count; when use_count = 0 - * the content may be removed from the memory cache. - */ - +/** The type of a content. */ typedef enum { CONTENT_HTML, CONTENT_TEXTPLAIN, @@ -48,28 +55,21 @@ typedef enum { CONTENT_PLUGIN, #endif CONTENT_OTHER, - CONTENT_UNKNOWN /* content-type not received yet */ + CONTENT_UNKNOWN /**< content-type not received yet */ } content_type; -struct box_position -{ - struct box* box; - int actual_box_x; - int actual_box_y; - int plot_index; - int pixel_offset; - int char_offset; -}; +/** Used in callbacks to indicate what has occurred. */ typedef enum { - CONTENT_MSG_LOADING, /* fetching or converting */ - CONTENT_MSG_READY, /* may be displayed */ - CONTENT_MSG_DONE, /* finished */ - CONTENT_MSG_ERROR, /* error occurred */ - CONTENT_MSG_STATUS, /* new status string */ - CONTENT_MSG_REDIRECT /* replacement URL */ + CONTENT_MSG_LOADING, /**< fetching or converting */ + CONTENT_MSG_READY, /**< may be displayed */ + CONTENT_MSG_DONE, /**< finished */ + CONTENT_MSG_ERROR, /**< error occurred */ + CONTENT_MSG_STATUS, /**< new status string */ + CONTENT_MSG_REDIRECT /**< replacement URL */ } content_msg; +/** Linked list of users of a content. */ struct content_user { void (*callback)(content_msg msg, struct content *c, void *p1, @@ -79,111 +79,50 @@ struct content_user struct content_user *next; }; -struct content -{ - char *url; - content_type type; - char *mime_type; - enum { - CONTENT_STATUS_TYPE_UNKNOWN, /* type not yet known */ - CONTENT_STATUS_LOADING, /* content is being fetched or converted - and is not safe to display */ - CONTENT_STATUS_READY, /* some parts of content still being - loaded, but can be displayed */ - CONTENT_STATUS_DONE /* all finished */ - } status; - unsigned long width, height; - unsigned long available_width; +/** Corresponds to a single URL. */ +struct content { + char *url; /**< URL, in standard form as from url_join. */ + content_type type; /**< Type of content. */ + char *mime_type; /**< Original MIME type of data, or 0. */ - union - { - struct - { - htmlParserCtxt* parser; - char* source; - int length; - struct box* layout; - colour background_colour; - unsigned int stylesheet_count; - struct content **stylesheet_content; - struct css_style* style; - struct { - struct box_position start; - struct box_position end; - enum {alter_UNKNOWN, alter_START, alter_END} altering; - int selected; /* 0 = unselected, 1 = selected */ - } text_selection; - struct font_set* fonts; - struct page_elements elements; - unsigned int object_count; /* images etc. */ - struct { - char *url; - struct content *content; - struct box *box; - } *object; - } html; + enum { + CONTENT_STATUS_TYPE_UNKNOWN, /**< Type not yet known. */ + CONTENT_STATUS_LOADING, /**< Content is being fetched or + converted and is not safe to display. */ + CONTENT_STATUS_READY, /**< Some parts of content still being + loaded, but can be displayed. */ + CONTENT_STATUS_DONE /**< All finished. */ + } status; /**< Current status. */ - struct - { - struct css_stylesheet *css; - unsigned int import_count; - char **import_url; - struct content **import_content; - } css; + unsigned long width, height; /**< Dimensions, if applicable. */ + unsigned long available_width; /**< Available width (eg window width). */ + + /** Data dependent on type. */ + union { + struct content_html_data html; + struct content_css_data css; #ifdef riscos - struct - { - char * data; - unsigned long length; - } jpeg; - - struct - { - png_structp png; - png_infop info; - unsigned long rowbytes; - int interlace; - osspriteop_area *sprite_area; - char *sprite_image; - enum { PNG_PALETTE, PNG_DITHER, PNG_DEEP } type; - } png; - - // Structure for the GIF handler - struct - { - char *data; // GIF data - unsigned long length; // Length of GIF data - unsigned long buffer_pos; // Position in the buffer - osspriteop_area *sprite_area; // Sprite area - char *sprite_image; // Sprite image - } gif; - - /* Structure for plugin */ - struct - { - char *data; /* object data */ - unsigned long length; /* object length */ - char* sysvar; /* system variable set by plugin */ - } plugin; + struct content_jpeg_data jpeg; + struct content_png_data png; + struct content_gif_data gif; + struct content_plugin_data plugin; #endif - /* downloads */ - struct - { - char *data; - unsigned long length; - } other; + struct content_other_data other; + } data; - } data; + struct cache_entry *cache; /**< Used by cache, 0 if not cached. */ + unsigned long size; /**< Estimated size of all data + associated with this content. */ + char *title; /**< Title for browser window. */ + unsigned int active; /**< Number of child fetches or + conversions currently in progress. */ + int error; /**< Non-0 if an error has occurred. */ + struct content_user *user_list; /**< List of users. */ + char status_message[80]; /**< Text for status bar. */ - struct cache_entry *cache; - unsigned long size; - char *title; - unsigned int active; - int error; - struct content_user *user_list; - char status_message[80]; - struct fetch *fetch; - unsigned long fetch_size, total_size; + struct fetch *fetch; /**< Associated fetch, or 0. */ + unsigned long fetch_size; /**< Amount of data fetched so far. */ + unsigned long total_size; /**< Total data size, 0 if unknown. */ }; diff --git a/content/other.c b/content/other.c index 0c1475148..a205a23d5 100644 --- a/content/other.c +++ b/content/other.c @@ -8,6 +8,7 @@ #include #include #include +#include "netsurf/content/content.h" #include "netsurf/content/other.h" #include "netsurf/utils/utils.h" diff --git a/content/other.h b/content/other.h index 7471a21f8..9e1dd8792 100644 --- a/content/other.h +++ b/content/other.h @@ -8,7 +8,12 @@ #ifndef _NETSURF_RISCOS_OTHER_H_ #define _NETSURF_RISCOS_OTHER_H_ -#include "netsurf/content/content.h" +struct content; + +struct content_other_data { + char *data; + unsigned long length; +}; void other_create(struct content *c); void other_process_data(struct content *c, char *data, unsigned long size); diff --git a/css/css.h b/css/css.h index 08464c1e3..f3405a407 100644 --- a/css/css.h +++ b/css/css.h @@ -86,6 +86,13 @@ struct css_selector { char *id; }; +struct content_css_data { + struct css_stylesheet *css; + unsigned int import_count; + char **import_url; + struct content **import_content; +}; + extern const struct css_style css_base_style; extern const struct css_style css_empty_style; diff --git a/render/html.h b/render/html.h index 18edc3ddf..cea2a7de8 100644 --- a/render/html.h +++ b/render/html.h @@ -8,7 +8,47 @@ #ifndef _NETSURF_RENDER_HTML_H_ #define _NETSURF_RENDER_HTML_H_ -#include "netsurf/content/content.h" +#include "netsurf/css/css.h" +#include "netsurf/render/box.h" + +struct box; +struct browser_window; +struct content; +struct object_params; + +struct box_position { + struct box *box; + int actual_box_x; + int actual_box_y; + int plot_index; + int pixel_offset; + int char_offset; +}; + +struct content_html_data { + htmlParserCtxt *parser; + char *source; + int length; + struct box *layout; + colour background_colour; + unsigned int stylesheet_count; + struct content **stylesheet_content; + struct css_style *style; + struct { + struct box_position start; + struct box_position end; + enum { alter_UNKNOWN, alter_START, alter_END } altering; + int selected; /* 0 = unselected, 1 = selected */ + } text_selection; + struct font_set *fonts; + struct page_elements elements; + unsigned int object_count; /* images etc. */ + struct { + char *url; + struct content *content; + struct box *box; + } *object; +}; void html_create(struct content *c); void html_process_data(struct content *c, char *data, unsigned long size); diff --git a/riscos/gif.h b/riscos/gif.h index b1a0cfc7c..b0c516b36 100644 --- a/riscos/gif.h +++ b/riscos/gif.h @@ -8,7 +8,17 @@ #ifndef _NETSURF_RISCOS_GIF_H_ #define _NETSURF_RISCOS_GIF_H_ -#include "netsurf/content/content.h" +#include "oslib/osspriteop.h" + +struct content; + +struct content_gif_data { + char *data; + unsigned long length; + unsigned long buffer_pos; + osspriteop_area *sprite_area; + char *sprite_image; +}; void nsgif_init(void); void nsgif_create(struct content *c); diff --git a/riscos/jpeg.h b/riscos/jpeg.h index d2ba94214..c81cff6b6 100644 --- a/riscos/jpeg.h +++ b/riscos/jpeg.h @@ -8,7 +8,12 @@ #ifndef _NETSURF_RISCOS_JPEG_H_ #define _NETSURF_RISCOS_JPEG_H_ -#include "netsurf/content/content.h" +struct content; + +struct content_jpeg_data { + char *data; + unsigned long length; +}; void jpeg_create(struct content *c); void jpeg_process_data(struct content *c, char *data, unsigned long size); diff --git a/riscos/plugin.h b/riscos/plugin.h index d71e5ef42..babc6310e 100644 --- a/riscos/plugin.h +++ b/riscos/plugin.h @@ -9,12 +9,20 @@ #define _NETSURF_RISCOS_PLUGIN_H_ #include -#include "netsurf/content/content.h" -#include "netsurf/render/box.h" - #include "oslib/plugin.h" #include "oslib/wimp.h" +struct box; +struct browser_window; +struct content; +struct object_params; + +struct content_plugin_data { + char *data; /* object data */ + unsigned long length; /* object length */ + char *sysvar; /* system variable set by plugin */ +}; + struct plugin_state { int dummy; }; diff --git a/riscos/png.h b/riscos/png.h index 370fa6ba3..2521630b8 100644 --- a/riscos/png.h +++ b/riscos/png.h @@ -8,7 +8,20 @@ #ifndef _NETSURF_RISCOS_PNG_H_ #define _NETSURF_RISCOS_PNG_H_ -#include "netsurf/content/content.h" +#include "libpng/png.h" +#include "oslib/osspriteop.h" + +struct content; + +struct content_png_data { + png_structp png; + png_infop info; + unsigned long rowbytes; + int interlace; + osspriteop_area *sprite_area; + char *sprite_image; + enum { PNG_PALETTE, PNG_DITHER, PNG_DEEP } type; +}; void nspng_init(void); void nspng_create(struct content *c);