Initial commit of the HEAD branch of the ELinks CVS repository, as of
[elinks/images.git] / src / cache / cache.h
blob1c3094fd1fecdae11f0a9c46beeac8a08269e953
1 /* $Id: cache.h,v 1.105 2005/07/27 23:38:32 jonas Exp $ */
3 #ifndef EL__CACHE_CACHE_H
4 #define EL__CACHE_CACHE_H
6 #include "main/object.h"
7 #include "util/lists.h"
8 #include "util/time.h"
10 struct listbox_item;
11 struct uri;
13 /* This enum describes the level of caching of certain cache entry. That is,
14 * under what conditions shall it be reloaded, if ever. The one with lowest
15 * value is most agressively cached, however the cache is most reluctant to
16 * cache the one with highest value. */
17 /* TODO: Invert order to be more intuitive. But be careful, many tests rely on
18 * current order. --Miciah,Zas */
19 enum cache_mode {
20 CACHE_MODE_INCREMENT = -1,
21 CACHE_MODE_ALWAYS,
22 CACHE_MODE_NORMAL,
23 CACHE_MODE_CHECK_IF_MODIFIED,
24 CACHE_MODE_FORCE_RELOAD,
25 CACHE_MODE_NEVER,
28 struct cache_entry {
29 OBJECT_HEAD(struct cache_entry);
31 /* Items in this list are ALLOCATED IN A NON-STANDARD WAY! Thus if you
32 * are gonna mess with them (you shouldn't), you need to use the
33 * mmap suite. */
34 struct list_head frag; /* -> struct fragment */
36 struct uri *uri; /* Identifier for the cached data */
37 struct uri *proxy_uri; /* Proxy identifier or same as @uri */
38 struct uri *redirect; /* Location we were redirected to */
40 unsigned char *head; /* The protocol header */
41 unsigned char *content_type; /* MIME type: <type> "/" <subtype> */
42 unsigned char *last_modified; /* Latest modification date */
43 unsigned char *etag; /* ETag value from the HTTP header */
44 unsigned char *ssl_info; /* SSL ciphers used during transfer */
45 unsigned char *encoding_info; /* Encoding used during transfer */
47 unsigned int id; /* Change each time entry is modified. */
49 off_t length; /* The expected and complete size */
50 off_t data_size; /* The actual size of all fragments */
52 struct listbox_item *box_item; /* Dialog data for cache manager */
54 timeval_T max_age; /* Expiration time */
56 unsigned int expire:1; /* Whether to honour max_age */
57 unsigned int preformatted:1; /* Has content been preformatted? */
58 unsigned int redirect_get:1; /* Follow redirect using get method? */
59 unsigned int incomplete:1; /* Has all data been downloaded? */
60 unsigned int valid:1; /* Is cache entry usable? */
62 /* This is a mark for internal workings of garbage_collection(), whether
63 * the cache_entry should be busted or not. You are not likely to see
64 * an entry with this set to 1 in wild nature ;-). */
65 unsigned int gc_target:1; /* The GC touch of death */
67 enum cache_mode cache_mode; /* Reload condition */
70 struct fragment {
71 LIST_HEAD(struct fragment);
73 off_t offset;
74 off_t length;
75 off_t real_length;
76 unsigned char data[1]; /* Must be last */
80 /* Searches the cache for an entry matching the URI. Returns NULL if no one
81 * matches. */
82 struct cache_entry *find_in_cache(struct uri *uri);
84 /* Searches the cache for a matching entry else a new one is added. Returns
85 * NULL if allocation fails. */
86 struct cache_entry *get_cache_entry(struct uri *uri);
88 /* Searches the cache for a matching entry and checks if it is still valid and
89 * usable. Returns NULL if the @cache_mode suggests to reload it again. */
90 struct cache_entry *get_validated_cache_entry(struct uri *uri, enum cache_mode cache_mode);
92 /* Checks if a dangling cache entry pointer is still valid. */
93 int cache_entry_is_valid(struct cache_entry *cached);
95 /* Follow all redirects and return the resulting cache entry or NULL if there
96 * are missing redirects. */
97 struct cache_entry *follow_cached_redirects(struct cache_entry *cached);
99 /* Works like find_in_cache(), but will follow cached redirects using
100 * follow_cached_redirects(). */
101 struct cache_entry *get_redirected_cache_entry(struct uri *uri);
103 /* Add a fragment to the @cached object at the given @offset containing @length
104 * bytes from the @data pointer. */
105 /* Returns -1 upon error,
106 * 1 if cache entry was enlarged,
107 * 0 if only old data were overwritten. */
108 int add_fragment(struct cache_entry *cached, off_t offset,
109 const unsigned char *data, ssize_t length);
111 /* Defragments the cache entry and returns the resulting fragment containing the
112 * complete source of all currently downloaded fragments. Returns NULL if
113 * validation of the fragments fails. */
114 struct fragment *get_cache_fragment(struct cache_entry *cached);
116 /* Should be called when creation of a new cache has been completed. Most
117 * importantly, it will updates cached->incomplete. */
118 void normalize_cache_entry(struct cache_entry *cached, off_t length);
120 void free_entry_to(struct cache_entry *cached, off_t offset);
121 void delete_entry_content(struct cache_entry *cached);
122 void delete_cache_entry(struct cache_entry *cached);
124 /* Sets up the cache entry to redirect to a new location
125 * @location decides where to redirect to by resolving it relative to the
126 * entry's URI.
127 * @get controls the method should be used when handling the redirect.
128 * @incomplete will become the new value of the incomplete member if it
129 * is >= 0.
130 * Returns the URI being redirected to or NULL if allocation failed.
132 struct uri *
133 redirect_cache(struct cache_entry *cached, unsigned char *location,
134 int get, int incomplete);
136 /* The garbage collector trigger. If @whole is zero, remove unused cache
137 * entries which are bigger than the cache size limit set by user. For @zero
138 * being one, remove all unused cache entries. */
139 void garbage_collection(int whole);
141 /* Used by the resource and memory info dialogs for getting information about
142 * the cache. */
143 unsigned longlong get_cache_size(void);
144 int get_cache_entry_count(void);
145 int get_cache_entry_used_count(void);
146 int get_cache_entry_loading_count(void);
148 #endif