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"
30 static char *__get_attribute(xmlNode *xml_node, const char *name)
35 val = xmlGetProp(xml_node, (const xmlChar *)name);
37 attr = strdup((const char *)val);
44 static void __get_attribute_into_bundle(xmlNode *xml_node, const char *name,
49 attr = __get_attribute(xml_node, name);
51 bundle_add_str(b, name, attr);
56 static int __parse_node(xmlNode *xml_node, GList **nodes)
58 resource_node_t *node;
60 if (strcmp((char *)xml_node->name, "node"))
63 node = calloc(1, sizeof(resource_node_t));
65 LOGE("Out of memory");
69 node->folder = __get_attribute(xml_node, "folder");
70 /* why we should use bundle here? */
71 node->attr = bundle_create();
72 if (node->attr == NULL) {
73 LOGE("Out of memory");
79 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_DPI,
81 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_DPI_RANGE,
83 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_WIDTH_RANGE,
85 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_LARGE,
87 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_SCREEN_BPP,
89 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_PLATFORM_VER,
91 __get_attribute_into_bundle(xml_node, RSC_NODE_ATTR_LANGUAGE,
94 *nodes = g_list_append(*nodes, node);
99 static char *_get_group_type(xmlNode *xml_node)
101 static const char delim[] = "-";
106 /* copy original string */
107 str = strdup((const char *)xml_node->name);
109 LOGE("Out of memory");
113 tok = strtok_r(str, delim, &ptr);
114 /* not a group element */
115 if (tok == NULL || strcmp(tok, "group")) {
120 tok = strtok_r(NULL, delim, &ptr);
121 /* invalid element */
133 static int __parse_group(xmlNode *xml_node, GList **groups)
137 resource_group_t *group;
139 type = _get_group_type(xml_node);
143 group = calloc(1, sizeof(resource_group_t));
145 LOGE("Out of memory");
151 group->folder = __get_attribute(xml_node, "folder");
153 for (tmp = xml_node->children; tmp; tmp = tmp->next) {
154 if (xml_node->type != XML_ELEMENT_NODE)
156 if (__parse_node(tmp, &group->node_list))
160 *groups = g_list_append(*groups, group);
165 static int __parse_resource(xmlNode *xml_node, resource_data_t **data)
169 *data = calloc(1, sizeof(resource_data_t));
171 LOGE("out of memory");
175 for (tmp = xml_node->children; tmp; tmp = tmp->next) {
176 if (tmp->type != XML_ELEMENT_NODE)
178 __parse_group(tmp, &(*data)->group_list);
184 #define SCHEMA_FILE SHARE_PREFIX"/res.xsd"
185 static int __validate_schema(const char *path)
187 xmlSchemaParserCtxt *parser_ctxt;
189 xmlSchemaValidCtxt *valid_ctxt;
192 parser_ctxt = xmlSchemaNewParserCtxt(SCHEMA_FILE);
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);
241 ret = __parse_resource(root, data);
248 static void __free_resource_node(gpointer data)
250 resource_node_t *node = (resource_node_t *)data;
253 bundle_free(node->attr);
257 static void __free_resource_group(gpointer data)
259 resource_group_t *group = (resource_group_t *)data;
264 g_list_free_full(group->node_list, __free_resource_node);
269 int _resource_close(resource_data_t *data)
274 g_list_free_full(data->group_list, __free_resource_group);