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"))
118 tok = strtok_r(NULL, delim, &ptr);
119 /* invalid element */
128 static int __parse_group(xmlNode *xml_node, GList **groups)
132 resource_group_t *group;
134 type = _get_group_type(xml_node);
138 group = calloc(1, sizeof(resource_group_t));
140 LOGE("Out of memory");
145 group->folder = __get_attribute(xml_node, "folder");
147 for (tmp = xml_node->children; tmp; tmp = tmp->next) {
148 if (xml_node->type != XML_ELEMENT_NODE)
150 if (__parse_node(tmp, &group->node_list))
154 *groups = g_list_append(*groups, group);
159 static int __parse_resource(xmlNode *xml_node, resource_data_t **data)
163 *data = calloc(1, sizeof(resource_data_t));
165 LOGE("out of memory");
169 for (tmp = xml_node->children; tmp; tmp = tmp->next) {
170 if (tmp->type != XML_ELEMENT_NODE)
172 __parse_group(tmp, &(*data)->group_list);
178 static int __validate_schema(const char *path)
180 xmlSchemaParserCtxt *parser_ctxt;
182 xmlSchemaValidCtxt *valid_ctxt;
185 parser_ctxt = xmlSchemaNewMemParserCtxt(res_schema, sizeof(res_schema));
186 if (parser_ctxt == NULL) {
187 LOGE("failed to create parser context");
191 schema = xmlSchemaParse(parser_ctxt);
192 if (schema == NULL) {
193 LOGE("failed to create schema");
194 xmlSchemaFreeParserCtxt(parser_ctxt);
198 valid_ctxt = xmlSchemaNewValidCtxt(schema);
199 if (valid_ctxt == NULL) {
200 LOGE("failed to create valid context");
201 xmlSchemaFree(schema);
202 xmlSchemaFreeParserCtxt(parser_ctxt);
206 ret = xmlSchemaValidateFile(valid_ctxt, path, 0);
208 LOGE("%s: validation failed(%d)", path, ret);
210 xmlSchemaFreeValidCtxt(valid_ctxt);
211 xmlSchemaFree(schema);
212 xmlSchemaFreeParserCtxt(parser_ctxt);
217 int _resource_open(const char *path, resource_data_t **data)
223 if (__validate_schema(path))
225 doc = xmlReadFile(path, NULL, 0);
228 root = xmlDocGetRootElement(doc);
230 ret = __parse_resource(root, data);
237 static void __free_resource_node(gpointer data)
239 resource_node_t *node = (resource_node_t *)data;
242 bundle_free(node->attr);
246 static void __free_resource_group(gpointer data)
248 resource_group_t *group = (resource_group_t *)data;
253 g_list_free_full(group->node_list, __free_resource_node);
258 int _resource_close(resource_data_t *data)
263 g_list_free_full(data->group_list, __free_resource_group);