Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
#include "mupdf.h"
3
 
4
typedef struct pdf_item_s pdf_item;
5
 
6
struct pdf_item_s
7
{
8
	void *drop_func;
9
	fz_obj *key;
10
	void *val;
11
	int age;
12
	pdf_item *next;
13
};
14
 
15
struct refkey
16
{
17
	void *drop_func;
18
	int num;
19
	int gen;
20
};
21
 
22
struct pdf_store_s
23
{
24
	fz_hash_table *hash;	/* hash for num/gen keys */
25
	pdf_item *root;		/* linked list for everything else */
26
};
27
 
28
pdf_store *
29
pdf_new_store(void)
30
{
31
	pdf_store *store;
32
	store = fz_malloc(sizeof(pdf_store));
33
	store->hash = fz_new_hash_table(4096, sizeof(struct refkey));
34
	store->root = NULL;
35
	return store;
36
}
37
 
38
void
39
pdf_store_item(pdf_store *store, void *keepfunc, void *drop_func, fz_obj *key, void *val)
40
{
41
	pdf_item *item;
42
 
43
	if (!store)
44
		return;
45
 
46
	item = fz_malloc(sizeof(pdf_item));
47
	item->drop_func = drop_func;
48
	item->key = fz_keep_obj(key);
49
	item->val = ((void*(*)(void*))keepfunc)(val);
50
	item->age = 0;
51
	item->next = NULL;
52
 
53
	if (fz_is_indirect(key))
54
	{
55
		struct refkey refkey;
56
		refkey.drop_func = drop_func;
57
		refkey.num = fz_to_num(key);
58
		refkey.gen = fz_to_gen(key);
59
		fz_hash_insert(store->hash, &refkey, item);
60
	}
61
	else
62
	{
63
		item->next = store->root;
64
		store->root = item;
65
	}
66
}
67
 
68
void *
69
pdf_find_item(pdf_store *store, void *drop_func, fz_obj *key)
70
{
71
	struct refkey refkey;
72
	pdf_item *item;
73
 
74
	if (!store)
75
		return NULL;
76
 
77
	if (key == NULL)
78
		return NULL;
79
 
80
	if (fz_is_indirect(key))
81
	{
82
		refkey.drop_func = drop_func;
83
		refkey.num = fz_to_num(key);
84
		refkey.gen = fz_to_gen(key);
85
		item = fz_hash_find(store->hash, &refkey);
86
		if (item)
87
		{
88
			item->age = 0;
89
			return item->val;
90
		}
91
	}
92
	else
93
	{
94
		for (item = store->root; item; item = item->next)
95
		{
96
			if (item->drop_func == drop_func && !fz_objcmp(item->key, key))
97
			{
98
				item->age = 0;
99
				return item->val;
100
			}
101
		}
102
	}
103
 
104
	return NULL;
105
}
106
 
107
void
108
pdf_remove_item(pdf_store *store, void *drop_func, fz_obj *key)
109
{
110
	struct refkey refkey;
111
	pdf_item *item, *prev, *next;
112
 
113
	if (fz_is_indirect(key))
114
	{
115
		refkey.drop_func = drop_func;
116
		refkey.num = fz_to_num(key);
117
		refkey.gen = fz_to_gen(key);
118
		item = fz_hash_find(store->hash, &refkey);
119
		if (item)
120
		{
121
			fz_hash_remove(store->hash, &refkey);
122
			((void(*)(void*))item->drop_func)(item->val);
123
			fz_drop_obj(item->key);
124
			fz_free(item);
125
		}
126
	}
127
	else
128
	{
129
		prev = NULL;
130
		for (item = store->root; item; item = next)
131
		{
132
			next = item->next;
133
			if (item->drop_func == drop_func && !fz_objcmp(item->key, key))
134
			{
135
				if (!prev)
136
					store->root = next;
137
				else
138
					prev->next = next;
139
				((void(*)(void*))item->drop_func)(item->val);
140
				fz_drop_obj(item->key);
141
				fz_free(item);
142
			}
143
			else
144
				prev = item;
145
		}
146
	}
147
}
148
 
149
void
150
pdf_age_store(pdf_store *store, int maxage)
151
{
152
	struct refkey *refkey;
153
	pdf_item *item, *prev, *next;
154
	int i;
155
 
156
	for (i = 0; i < fz_hash_len(store->hash); i++)
157
	{
158
		refkey = fz_hash_get_key(store->hash, i);
159
		item = fz_hash_get_val(store->hash, i);
160
		if (item && ++item->age > maxage)
161
		{
162
			fz_hash_remove(store->hash, refkey);
163
			((void(*)(void*))item->drop_func)(item->val);
164
			fz_drop_obj(item->key);
165
			fz_free(item);
166
			i--; /* items with same hash may move into place */
167
		}
168
	}
169
 
170
	prev = NULL;
171
	for (item = store->root; item; item = next)
172
	{
173
		next = item->next;
174
		if (++item->age > maxage)
175
		{
176
			if (!prev)
177
				store->root = next;
178
			else
179
				prev->next = next;
180
			((void(*)(void*))item->drop_func)(item->val);
181
			fz_drop_obj(item->key);
182
			fz_free(item);
183
		}
184
		else
185
			prev = item;
186
	}
187
}
188
 
189
void
190
pdf_free_store(pdf_store *store)
191
{
192
	pdf_age_store(store, 0);
193
	fz_free_hash(store->hash);
194
	fz_free(store);
195
}
196
 
197
void
198
pdf_debug_store(pdf_store *store)
199
{
200
	pdf_item *item;
201
	pdf_item *next;
202
	struct refkey *refkey;
203
	int i;
204
 
205
	printf("-- resource store contents --\n");
206
 
207
	for (i = 0; i < fz_hash_len(store->hash); i++)
208
	{
209
		refkey = fz_hash_get_key(store->hash, i);
210
		item = fz_hash_get_val(store->hash, i);
211
		if (item)
212
			printf("store[%d] (%d %d R) = %p\n", i, refkey->num, refkey->gen, item->val);
213
	}
214
 
215
	for (item = store->root; item; item = next)
216
	{
217
		next = item->next;
218
		printf("store[*] ");
219
		fz_debug_obj(item->key);
220
		printf(" = %p\n", item->val);
221
	}
222
}