2 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <libxml/tree.h>
23 #include <libxml/xmlschemas.h>
28 #include "aul_rsc_mgr_internal.h"
29 #include "aul_rsc_mgr_schema.h"
31 static char *__get_attribute(xmlNode *xml_node, const char *name)
36 val = xmlGetProp(xml_node, (const xmlChar *)name);
38 attr = strdup((const char *)val);
45 static void __get_attribute_into_bundle(xmlNode *xml_node, const char *name,
50 attr = __get_attribute(xml_node, name);
52 bundle_add_str(b, name, attr);
57 static int __parse_node(xmlNode *xml_node, GList **nodes)
59 resource_node_t *node;
61 if (strcmp((char *)xml_node->name, "node"))
64 node = calloc(1, sizeof(resource_node_t));
66 LOGE("Out of memory");
70 node->folder = __get_attribute(xml_node, "folder");
71 /* why we should use bundle here? */
72 node->attr = bundle_create();
73 if (node->attr == NULL) {
74 LOGE("Out of memory");
80 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_DPI,
82 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_DPI_RANGE,
84 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_WIDTH_RANGE,
86 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_LARGE,
88 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_BPP,
90 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_PLATFORM_VER,
92 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_LANGUAGE,
95 *nodes = g_list_append(*nodes, node);
100 static char *_get_group_type(xmlNode *xml_node)
102 static const char delim[] = "-";
107 /* copy original string */
108 str = strdup((const char *)xml_node->name);
110 LOGE("Out of memory");
114 tok = strtok_r(str, delim, &ptr);
115 /* not a group element */
116 if (tok == NULL || strcmp(tok, "group")) {
121 tok = strtok_r(NULL, delim, &ptr);
122 /* invalid element */
134 static int __parse_group(xmlNode *xml_node, GList **groups)
138 resource_group_t *group;
140 type = _get_group_type(xml_node);
144 group = calloc(1, sizeof(resource_group_t));
146 LOGE("Out of memory");
152 group->folder = __get_attribute(xml_node, "folder");
154 for (tmp = xml_node->children; tmp; tmp = tmp->next) {
155 if (xml_node->type != XML_ELEMENT_NODE)
157 if (__parse_node(tmp, &group->node_list))
161 *groups = g_list_append(*groups, group);
166 static int __parse_resource(xmlNode *xml_node, resource_data_t **data)
170 *data = calloc(1, sizeof(resource_data_t));
172 LOGE("out of memory");
176 for (tmp = xml_node->children; tmp; tmp = tmp->next) {
177 if (tmp->type != XML_ELEMENT_NODE)
179 __parse_group(tmp, &(*data)->group_list);
185 static int __validate_schema(const char *path)
187 xmlSchemaParserCtxt *parser_ctxt;
189 xmlSchemaValidCtxt *valid_ctxt;
192 parser_ctxt = xmlSchemaNewMemParserCtxt(res_schema, sizeof(res_schema));
193 if (parser_ctxt == NULL) {
194 LOGE("failed to create parser context");
198 schema = xmlSchemaParse(parser_ctxt);
199 if (schema == NULL) {
200 LOGE("failed to create schema");
201 xmlSchemaFreeParserCtxt(parser_ctxt);
205 valid_ctxt = xmlSchemaNewValidCtxt(schema);
206 if (valid_ctxt == NULL) {
207 LOGE("failed to create valid context");
208 xmlSchemaFree(schema);
209 xmlSchemaFreeParserCtxt(parser_ctxt);
213 ret = xmlSchemaValidateFile(valid_ctxt, path, 0);
215 LOGE("%s: validation failed(%d)", path, ret);
217 xmlSchemaFreeValidCtxt(valid_ctxt);
218 xmlSchemaFree(schema);
219 xmlSchemaFreeParserCtxt(parser_ctxt);
224 int _resource_open(const char *path, resource_data_t **data)
230 if (__validate_schema(path))
232 doc = xmlReadFile(path, NULL, 0);
235 root = xmlDocGetRootElement(doc);
237 ret = __parse_resource(root, data);
244 static void __free_resource_node(gpointer data)
246 resource_node_t *node = (resource_node_t *)data;
249 bundle_free(node->attr);
253 static void __free_resource_group(gpointer data)
255 resource_group_t *group = (resource_group_t *)data;
260 g_list_free_full(group->node_list, __free_resource_node);
265 int _resource_close(resource_data_t *data)
270 g_list_free_full(data->group_list, __free_resource_group);