Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
#include "muxps.h"
3
 
4
static xml_element *
5
xps_find_resource(xps_context *ctx, xps_resource *dict, char *name, char **urip)
6
{
7
	xps_resource *head, *node;
8
	for (head = dict; head; head = head->parent)
9
	{
10
		for (node = head; node; node = node->next)
11
		{
12
			if (!strcmp(node->name, name))
13
			{
14
				if (urip && head->base_uri)
15
					*urip = head->base_uri;
16
				return node->data;
17
			}
18
		}
19
	}
20
	return NULL;
21
}
22
 
23
static xml_element *
24
xps_parse_resource_reference(xps_context *ctx, xps_resource *dict, char *att, char **urip)
25
{
26
	char name[1024];
27
	char *s;
28
 
29
	if (strstr(att, "{StaticResource ") != att)
30
		return NULL;
31
 
32
	fz_strlcpy(name, att + 16, sizeof name);
33
	s = strrchr(name, '}');
34
	if (s)
35
		*s = 0;
36
 
37
	return xps_find_resource(ctx, dict, name, urip);
38
}
39
 
40
void
41
xps_resolve_resource_reference(xps_context *ctx, xps_resource *dict,
42
		char **attp, xml_element **tagp, char **urip)
43
{
44
	if (*attp)
45
	{
46
		xml_element *rsrc = xps_parse_resource_reference(ctx, dict, *attp, urip);
47
		if (rsrc)
48
		{
49
			*attp = NULL;
50
			*tagp = rsrc;
51
		}
52
	}
53
}
54
 
55
static int
56
xps_parse_remote_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, char *source_att)
57
{
58
	char part_name[1024];
59
	char part_uri[1024];
60
	xps_resource *dict;
61
	xps_part *part;
62
	xml_element *xml;
63
	char *s;
64
	int code;
65
 
66
	/* External resource dictionaries MUST NOT reference other resource dictionaries */
67
	xps_absolute_path(part_name, base_uri, source_att, sizeof part_name);
68
	part = xps_read_part(ctx, part_name);
69
	if (!part)
70
	{
71
		return fz_throw("cannot find remote resource part '%s'", part_name);
72
	}
73
 
74
	xml = xml_parse_document(part->data, part->size);
75
	if (!xml)
76
	{
77
		xps_free_part(ctx, part);
78
		return fz_rethrow(-1, "cannot parse xml");
79
	}
80
 
81
	if (strcmp(xml_tag(xml), "ResourceDictionary"))
82
	{
83
		xml_free_element(xml);
84
		xps_free_part(ctx, part);
85
		return fz_throw("expected ResourceDictionary element (found %s)", xml_tag(xml));
86
	}
87
 
88
	fz_strlcpy(part_uri, part_name, sizeof part_uri);
89
	s = strrchr(part_uri, '/');
90
	if (s)
91
		s[1] = 0;
92
 
93
	code = xps_parse_resource_dictionary(ctx, &dict, part_uri, xml);
94
	if (code)
95
	{
96
		xml_free_element(xml);
97
		xps_free_part(ctx, part);
98
		return fz_rethrow(code, "cannot parse remote resource dictionary: %s", part_uri);
99
	}
100
 
101
	dict->base_xml = xml; /* pass on ownership */
102
 
103
	xps_free_part(ctx, part);
104
 
105
	*dictp = dict;
106
	return fz_okay;
107
}
108
 
109
int
110
xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, xml_element *root)
111
{
112
	xps_resource *head;
113
	xps_resource *entry;
114
	xml_element *node;
115
	char *source;
116
	char *key;
117
	int code;
118
 
119
	source = xml_att(root, "Source");
120
	if (source)
121
	{
122
		code = xps_parse_remote_resource_dictionary(ctx, dictp, base_uri, source);
123
		if (code)
124
			return fz_rethrow(code, "cannot parse remote resource dictionary");
125
		return fz_okay;
126
	}
127
 
128
	head = NULL;
129
 
130
	for (node = xml_down(root); node; node = xml_next(node))
131
	{
132
		key = xml_att(node, "x:Key");
133
		if (key)
134
		{
135
			entry = fz_malloc(sizeof(xps_resource));
136
			entry->name = key;
137
			entry->base_uri = NULL;
138
			entry->base_xml = NULL;
139
			entry->data = node;
140
			entry->next = head;
141
			entry->parent = NULL;
142
			head = entry;
143
		}
144
	}
145
 
146
	if (head)
147
		head->base_uri = fz_strdup(base_uri);
148
	else
149
		return fz_throw("empty resource dictionary");
150
 
151
	*dictp = head;
152
	return fz_okay;
153
}
154
 
155
void
156
xps_free_resource_dictionary(xps_context *ctx, xps_resource *dict)
157
{
158
	xps_resource *next;
159
	while (dict)
160
	{
161
		next = dict->next;
162
		if (dict->base_xml)
163
			xml_free_element(dict->base_xml);
164
		if (dict->base_uri)
165
			fz_free(dict->base_uri);
166
		fz_free(dict);
167
		dict = next;
168
	}
169
}
170
 
171
void
172
xps_debug_resource_dictionary(xps_resource *dict)
173
{
174
	while (dict)
175
	{
176
		if (dict->base_uri)
177
			printf("URI = '%s'\n", dict->base_uri);
178
		printf("KEY = '%s' VAL = %p\n", dict->name, dict->data);
179
		if (dict->parent)
180
		{
181
			printf("PARENT = {\n");
182
			xps_debug_resource_dictionary(dict->parent);
183
			printf("}\n");
184
		}
185
		dict = dict->next;
186
	}
187
}