1 /*****************************************************************
2 * gmerlin - a general purpose multimedia framework and applications
3 *
4 * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5 * gmerlin-general@lists.sourceforge.net
6 * http://gmerlin.sourceforge.net
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * *****************************************************************/
21
22 #include <stdlib.h>
23 #include <string.h>
24 // #include <locale.h>
25
26 #include <gmerlin/cfg_registry.h>
27 #include <registry_priv.h>
28 #include <gmerlin/utils.h>
29 #include <gmerlin/xmlutils.h>
30
load_item(xmlDocPtr xml_doc,xmlNodePtr xml_item,bg_cfg_section_t * cfg_section)31 static void load_item(xmlDocPtr xml_doc, xmlNodePtr xml_item,
32 bg_cfg_section_t * cfg_section)
33 {
34 char * tmp_type;
35 char * tmp_string;
36 char * start;
37
38 bg_parameter_info_t info;
39
40 bg_cfg_item_t * item;
41
42 memset(&info, 0, sizeof(info));
43
44 tmp_type = BG_XML_GET_PROP(xml_item, "type");
45 info.name = BG_XML_GET_PROP(xml_item, "name");
46
47 if(!tmp_type || !info.name)
48 {
49 if(tmp_type)
50 xmlFree(tmp_type);
51 if(info.name)
52 xmlFree(info.name);
53 return;
54 }
55
56 /* Check for the type */
57
58 if(!strcmp(tmp_type, "int"))
59 {
60 info.type = BG_PARAMETER_INT;
61 }
62 else if(!strcmp(tmp_type, "float"))
63 {
64 info.type = BG_PARAMETER_FLOAT;
65 }
66 else if(!strcmp(tmp_type, "string"))
67 {
68 info.type = BG_PARAMETER_STRING;
69 }
70 else if(!strcmp(tmp_type, "string_hidden"))
71 {
72 info.type = BG_PARAMETER_STRING_HIDDEN;
73 }
74 else if(!strcmp(tmp_type, "color"))
75 {
76 info.type = BG_PARAMETER_COLOR_RGBA;
77 }
78 else if(!strcmp(tmp_type, "time"))
79 {
80 info.type = BG_PARAMETER_TIME;
81 }
82 else if(!strcmp(tmp_type, "pos"))
83 {
84 info.type = BG_PARAMETER_POSITION;
85 }
86 else
87 {
88 return;
89 }
90
91 /* Find the item */
92
93 item = bg_cfg_section_find_item(cfg_section, &info);
94
95 tmp_string = (char*)xmlNodeListGetString(xml_doc, xml_item->children, 1);
96
97 switch(item->type)
98 {
99 case BG_CFG_INT:
100 sscanf(tmp_string, "%d", &item->value.val_i);
101 break;
102 case BG_CFG_TIME:
103 sscanf(tmp_string, "%" PRId64, &item->value.val_time);
104 break;
105 case BG_CFG_FLOAT:
106 sscanf(tmp_string, "%lf", &item->value.val_f);
107 break;
108 case BG_CFG_STRING:
109 item->value.val_str = bg_strdup(item->value.val_str,
110 tmp_string);
111 break;
112 case BG_CFG_STRING_HIDDEN:
113 if(item->value.val_str)
114 {
115 free(item->value.val_str);
116 item->value.val_str = NULL;
117 }
118 if(tmp_string && (*tmp_string != '\0'))
119 item->value.val_str = bg_descramble_string(tmp_string);
120
121 break;
122 case BG_CFG_COLOR:
123 start = tmp_string;
124 sscanf(tmp_string, "%f %f %f %f",
125 &item->value.val_color[0],
126 &item->value.val_color[1],
127 &item->value.val_color[2],
128 &item->value.val_color[3]);
129 break;
130 case BG_CFG_POSITION:
131 start = tmp_string;
132 sscanf(tmp_string, "%lf %lf",
133 &item->value.val_pos[0],
134 &item->value.val_pos[1]);
135 break;
136 }
137 if(tmp_string)
138 xmlFree(tmp_string);
139 if(info.name)
140 xmlFree(info.name);
141 if(tmp_type)
142 xmlFree(tmp_type);
143 }
144
bg_cfg_xml_2_section(xmlDocPtr xml_doc,xmlNodePtr xml_section,bg_cfg_section_t * cfg_section)145 void bg_cfg_xml_2_section(xmlDocPtr xml_doc,
146 xmlNodePtr xml_section,
147 bg_cfg_section_t * cfg_section)
148 {
149 xmlNodePtr cur;
150 char * tmp_string;
151 bg_cfg_section_t * cfg_child_section;
152
153 cur = xml_section->children;
154
155 tmp_string = BG_XML_GET_PROP(xml_section, "gettext_domain");
156 if(tmp_string)
157 {
158 cfg_section->gettext_domain =
159 bg_strdup(cfg_section->gettext_domain, tmp_string);
160 xmlFree(tmp_string);
161 }
162 tmp_string = BG_XML_GET_PROP(xml_section, "gettext_directory");
163 if(tmp_string)
164 {
165 cfg_section->gettext_directory =
166 bg_strdup(cfg_section->gettext_directory, tmp_string);
167 xmlFree(tmp_string);
168 }
169
170 while(cur)
171 {
172 if(!cur->name)
173 {
174 cur = cur->next;
175 continue;
176 }
177 /* Load items */
178 else if(!BG_XML_STRCMP(cur->name, "ITEM"))
179 {
180 load_item(xml_doc, cur, cfg_section);
181 }
182 /* Load child */
183 else if(!BG_XML_STRCMP(cur->name, "SECTION"))
184 {
185 tmp_string = BG_XML_GET_PROP(cur, "name");
186 if(tmp_string)
187 {
188 cfg_child_section = bg_cfg_section_find_subsection(cfg_section, tmp_string);
189 bg_cfg_xml_2_section(xml_doc, cur, cfg_child_section);
190 xmlFree(tmp_string);
191 }
192 }
193 cur = cur->next;
194 }
195 }
196
bg_cfg_registry_load(bg_cfg_registry_t * r,const char * filename)197 void bg_cfg_registry_load(bg_cfg_registry_t * r, const char * filename)
198 {
199 xmlDocPtr xml_doc;
200 xmlNodePtr node;
201 bg_cfg_section_t * cfg_section;
202 char * tmp_string;
203
204 if(!filename)
205 return;
206
207 xml_doc = bg_xml_parse_file(filename);
208
209 if(!xml_doc)
210 return;
211
212 node = xml_doc->children;
213
214 if(BG_XML_STRCMP(node->name, "REGISTRY"))
215 {
216 xmlFreeDoc(xml_doc);
217 return;
218 }
219
220 node = node->children;
221
222 while(node)
223 {
224 if(node->name && !BG_XML_STRCMP(node->name, "SECTION"))
225 {
226 tmp_string = BG_XML_GET_PROP(node, "name");
227 if(tmp_string)
228 {
229 cfg_section = bg_cfg_registry_find_section(r, tmp_string);
230 bg_cfg_xml_2_section(xml_doc, node, cfg_section);
231 xmlFree(tmp_string);
232 }
233 }
234 node = node->next;
235 }
236
237 xmlFreeDoc(xml_doc);
238 }
239
bg_cfg_section_2_xml(const bg_cfg_section_t * section,xmlNodePtr xml_section)240 void bg_cfg_section_2_xml(const bg_cfg_section_t * section, xmlNodePtr xml_section)
241 {
242 char * tmp_string;
243 bg_cfg_item_t * item;
244 bg_cfg_section_t * tmp_section;
245
246 char buffer[1024];
247
248 xmlNodePtr xml_item, xml_child;
249
250 /* Save items */
251
252 item = section->items;
253
254 if(section->gettext_domain)
255 BG_XML_SET_PROP(xml_section, "gettext_domain", section->gettext_domain);
256 if(section->gettext_directory)
257 BG_XML_SET_PROP(xml_section, "gettext_directory", section->gettext_directory);
258
259 xmlAddChild(xml_section, BG_XML_NEW_TEXT("\n"));
260
261 while(item)
262 {
263 xml_item = xmlNewTextChild(xml_section, NULL, (xmlChar*)"ITEM", NULL);
264 BG_XML_SET_PROP(xml_item, "name", item->name);
265
266 switch(item->type)
267 {
268 case BG_CFG_INT:
269 BG_XML_SET_PROP(xml_item, "type", "int");
270 sprintf(buffer, "%d", item->value.val_i);
271 xmlAddChild(xml_item, BG_XML_NEW_TEXT(buffer));
272 break;
273 case BG_CFG_TIME:
274 BG_XML_SET_PROP(xml_item, "type", "time");
275 sprintf(buffer, "%" PRId64, item->value.val_time);
276 xmlAddChild(xml_item, BG_XML_NEW_TEXT(buffer));
277 break;
278 case BG_CFG_FLOAT:
279 BG_XML_SET_PROP(xml_item, "type", "float");
280 sprintf(buffer, "%.15e", item->value.val_f);
281 xmlAddChild(xml_item, BG_XML_NEW_TEXT(buffer));
282 break;
283 case BG_CFG_STRING:
284 BG_XML_SET_PROP(xml_item, "type", "string");
285 /* Yes, that's stupid */
286 if(item->value.val_str)
287 xmlAddChild(xml_item, BG_XML_NEW_TEXT(item->value.val_str));
288 break;
289 case BG_CFG_STRING_HIDDEN:
290 BG_XML_SET_PROP(xml_item, "type", "string_hidden");
291 /* Yes, that's stupid */
292 if(item->value.val_str)
293 {
294 tmp_string = bg_scramble_string(item->value.val_str);
295 xmlAddChild(xml_item, BG_XML_NEW_TEXT(tmp_string));
296 free(tmp_string);
297 }
298 break;
299 case BG_CFG_COLOR:
300 BG_XML_SET_PROP(xml_item, "type", "color");
301 sprintf(buffer, "%f %f %f %f",
302 item->value.val_color[0],
303 item->value.val_color[1],
304 item->value.val_color[2],
305 item->value.val_color[3]);
306 xmlAddChild(xml_item, BG_XML_NEW_TEXT(buffer));
307 break;
308 case BG_CFG_POSITION:
309 BG_XML_SET_PROP(xml_item, "type", "pos");
310 sprintf(buffer, "%f %f",
311 item->value.val_pos[0],
312 item->value.val_pos[1]);
313 xmlAddChild(xml_item, BG_XML_NEW_TEXT(buffer));
314 break;
315 }
316 xmlAddChild(xml_section, BG_XML_NEW_TEXT("\n"));
317
318 item = item->next;
319 }
320
321 /* Save child sections */
322
323 tmp_section = section->children;
324 while(tmp_section)
325 {
326 xml_child = xmlNewTextChild(xml_section, NULL, (xmlChar*)"SECTION", NULL);
327 BG_XML_SET_PROP(xml_child, "name", tmp_section->name);
328
329 bg_cfg_section_2_xml(tmp_section, xml_child);
330 xmlAddChild(xml_section, BG_XML_NEW_TEXT("\n"));
331
332 tmp_section = tmp_section->next;
333 }
334 }
335
bg_cfg_registry_save(bg_cfg_registry_t * r,const char * filename)336 void bg_cfg_registry_save(bg_cfg_registry_t * r, const char * filename)
337 {
338 xmlDocPtr xml_doc;
339 xmlNodePtr xml_registry, xml_section;
340
341 bg_cfg_section_t * tmp_section;
342 if(!filename)
343 return;
344
345 xml_doc = xmlNewDoc((xmlChar*)"1.0");
346 xml_registry = xmlNewDocRawNode(xml_doc, NULL, (xmlChar*)"REGISTRY", NULL);
347 xmlDocSetRootElement(xml_doc, xml_registry);
348
349 xmlAddChild(xml_registry, BG_XML_NEW_TEXT("\n"));
350
351 tmp_section = r->sections;
352 while(tmp_section)
353 {
354 xml_section = xmlNewTextChild(xml_registry, NULL, (xmlChar*)"SECTION", NULL);
355 BG_XML_SET_PROP(xml_section, "name", tmp_section->name);
356
357 bg_cfg_section_2_xml(tmp_section, xml_section);
358 tmp_section = tmp_section->next;
359
360 xmlAddChild(xml_registry, BG_XML_NEW_TEXT("\n"));
361
362 }
363 xmlSaveFile(filename, xml_doc);
364 xmlFreeDoc(xml_doc);
365 }
366
bg_cfg_section_dump(bg_cfg_section_t * section,const char * filename)367 void bg_cfg_section_dump(bg_cfg_section_t * section, const char * filename)
368 {
369 xmlDocPtr xml_doc;
370 xmlNodePtr xml_section;
371 xml_doc = xmlNewDoc((xmlChar*)"1.0");
372 xml_section = xmlNewDocRawNode(xml_doc, NULL, (xmlChar*)"SECTION", NULL);
373 xmlDocSetRootElement(xml_doc, xml_section);
374 BG_XML_SET_PROP(xml_section, "name", section->name);
375 bg_cfg_section_2_xml(section, xml_section);
376 xmlSaveFile(filename, xml_doc);
377 xmlFreeDoc(xml_doc);
378 }
379