Add function to set/get private data
[platform/core/uifw/tts.git] / common / tts_config_parser.c
1 /*
2 *  Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <dlog.h>
15 #include <stdio.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <vconf.h>
19
20 #include "tts_config_parser.h"
21 #include "tts_defs.h"
22
23
24 #define TTS_TAG_ENGINE_BASE_TAG         "tts-engine"
25 #define TTS_TAG_ENGINE_NAME             "name"
26 #define TTS_TAG_ENGINE_ID               "id"
27 #define TTS_TAG_ENGINE_SETTING          "setting"
28 #define TTS_TAG_ENGINE_VOICE_SET        "voices"
29 #define TTS_TAG_ENGINE_VOICE            "voice"
30 #define TTS_TAG_ENGINE_VOICE_TYPE       "type"
31 #define TTS_TAG_ENGINE_PITCH_SUPPORT    "pitch-support"
32
33 #define TTS_TAG_CONFIG_BASE_TAG         "tts-config"
34 #define TTS_TAG_CONFIG_ENGINE_ID        "engine"
35 #define TTS_TAG_CONFIG_ENGINE_SETTING   "engine-setting"
36 #define TTS_TAG_CONFIG_AUTO_VOICE       "auto"
37 #define TTS_TAG_CONFIG_VOICE_TYPE       "voice-type"
38 #define TTS_TAG_CONFIG_LANGUAGE         "language"
39 #define TTS_TAG_CONFIG_SPEECH_RATE      "speech-rate"
40 #define TTS_TAG_CONFIG_PITCH            "pitch"
41 #define TTS_TAG_VOICE_TYPE_FEMALE       "female"
42 #define TTS_TAG_VOICE_TYPE_MALE         "male"
43 #define TTS_TAG_VOICE_TYPE_CHILD        "child"
44
45
46 extern char* tts_tag();
47
48 static xmlDocPtr g_config_doc = NULL;
49
50 int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info)
51 {
52         if (NULL == path || NULL == engine_info) {
53                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
54                 return -1;
55         }
56
57         xmlDocPtr doc = NULL;
58         xmlNodePtr cur = NULL;
59         xmlChar *key = NULL;
60         xmlChar *attr = NULL;
61
62         doc = xmlParseFile(path);
63         if (doc == NULL) {
64                 return -1;
65         }
66
67         cur = xmlDocGetRootElement(doc);
68         if (cur == NULL) {
69                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
70                 xmlFreeDoc(doc);
71                 return -1;
72         }
73
74         if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
75                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT 'tts-engine'");
76                 xmlFreeDoc(doc);
77                 return -1;
78         }
79
80         cur = cur->xmlChildrenNode;
81         if (cur == NULL) {
82                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
83                 xmlFreeDoc(doc);
84                 return -1;
85         }
86
87         /* alloc engine info */
88         tts_engine_info_s* temp;
89         temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
90         if (NULL == temp) {
91                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
92                 xmlFreeDoc(doc);
93                 return -1;
94         }
95
96         temp->name = NULL;
97         temp->uuid = NULL;
98         temp->voices = NULL;
99         temp->setting = NULL;
100         temp->pitch_support = false;
101
102         while (cur != NULL) {
103                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
104                         key = xmlNodeGetContent(cur);
105                         if (NULL != key) {
106                                 if (NULL != temp->name) free(temp->name);
107                                 temp->name = strdup((char*)key);
108                                 xmlFree(key);
109                         } else {
110                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
111                         }
112                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_ID)) {
113                         key = xmlNodeGetContent(cur);
114                         if (NULL != key) {
115                                 if (NULL != temp->uuid) free(temp->uuid);
116                                 temp->uuid = strdup((char*)key);
117                                 xmlFree(key);
118                         } else {
119                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
120                         }
121                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_SETTING)) {
122                         key = xmlNodeGetContent(cur);
123                         if (NULL != key) {
124                                 if (NULL != temp->setting)      free(temp->setting);
125                                 temp->setting = strdup((char*)key);
126                                 xmlFree(key);
127                         } else {
128                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
129                         }
130                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
131                         xmlNodePtr voice_node = NULL;
132                         voice_node = cur->xmlChildrenNode;
133
134                         while (NULL != voice_node) {
135                                 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
136
137                                         tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
138                                         if (NULL == temp_voice) {
139                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
140                                                 break;
141                                         }
142
143                                         attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
144                                         if (NULL != attr) {
145                                                 if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
146                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
147                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
148                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
149                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
150                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
151                                                 } else {
152                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
153                                                 }
154                                                 xmlFree(attr);
155                                         } else {
156                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
157                                         }
158
159                                         key = xmlNodeGetContent(voice_node);
160                                         if (NULL != key) {
161                                                 if (NULL != temp_voice->language)       free(temp_voice->language);
162                                                 temp_voice->language = strdup((char*)key);
163                                                 xmlFree(key);
164                                                 temp->voices = g_slist_append(temp->voices, temp_voice);
165                                         } else {
166                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
167                                                 if (NULL != temp_voice) {
168                                                         free(temp_voice);
169                                                 }
170                                         }
171                                 }
172                                 voice_node = voice_node->next;
173                         }
174                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_PITCH_SUPPORT)) {
175                         key = xmlNodeGetContent(cur);
176                         if (NULL != key) {
177                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
178                                         temp->pitch_support = true;
179                                 }
180                                 xmlFree(key);
181                         } else {
182                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
183                         }
184                 }
185                 cur = cur->next;
186         }
187
188         xmlFreeDoc(doc);
189
190         if (NULL == temp->name || NULL == temp->uuid) {
191                 /* Invalid engine */
192                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid engine : %s", path);
193                 tts_parser_free_engine_info(temp);
194                 return -1;
195         }
196
197         *engine_info = temp;
198
199         return 0;
200 }
201
202 int tts_parser_free_engine_info(tts_engine_info_s* engine_info)
203 {
204         if (NULL == engine_info) {
205                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
206                 return -1;
207         }
208
209         if (NULL != engine_info->name)          free(engine_info->name);
210         if (NULL != engine_info->uuid)          free(engine_info->uuid);
211         if (NULL != engine_info->setting)       free(engine_info->setting);
212
213         tts_config_voice_s *temp_voice;
214         temp_voice = g_slist_nth_data(engine_info->voices, 0);
215
216         while (NULL != temp_voice) {
217                 if (NULL != temp_voice) {
218                         if (NULL != temp_voice->language)       free(temp_voice->language);
219                         engine_info->voices = g_slist_remove(engine_info->voices, temp_voice);
220                         free(temp_voice);
221                 }
222
223                 temp_voice = g_slist_nth_data(engine_info->voices, 0);
224         }
225
226         if (NULL != engine_info)        free(engine_info);
227
228         return 0;       
229 }
230
231 int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
232 {
233         if (NULL == engine_info) {
234                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
235                 return -1;
236         }
237
238         SLOG(LOG_DEBUG, tts_tag(), "== get engine info ==");
239         SLOG(LOG_DEBUG, tts_tag(), " name : %s", engine_info->name);
240         SLOG(LOG_DEBUG, tts_tag(), " id   : %s", engine_info->uuid);
241         if (NULL != engine_info->setting)
242                 SLOG(LOG_DEBUG, tts_tag(), " setting : %s", engine_info->setting);
243
244         SLOG(LOG_DEBUG, tts_tag(), " voices");
245         GSList *iter = NULL;
246         tts_config_voice_s *temp_voice;
247
248         if (g_slist_length(engine_info->voices) > 0) {
249                 /* Get a first item */
250                 iter = g_slist_nth(engine_info->voices, 0);
251
252                 int i = 1;      
253                 while (NULL != iter) {
254                         /*Get handle data from list*/
255                         temp_voice = iter->data;
256
257                         SLOG(LOG_DEBUG, tts_tag(), "  [%dth] type(%d) lang(%s)", 
258                                 i, temp_voice->type, temp_voice->language);
259
260                         /*Get next item*/
261                         iter = g_slist_next(iter);
262                         i++;
263                 }
264         } else {
265                 SLOG(LOG_ERROR, tts_tag(), "  Voice is NONE");
266         }
267
268         SLOG(LOG_DEBUG, tts_tag(), "=====================");
269
270         return 0;
271 }
272
273 int tts_parser_load_config(tts_config_s** config_info)
274 {
275         if (NULL == config_info) {
276                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
277                 return -1;
278         }
279
280         xmlDocPtr doc = NULL;
281         xmlNodePtr cur = NULL;
282         xmlChar *key;
283         bool is_default_open = false;
284
285         if (0 != access(TTS_CONFIG, F_OK)) {
286                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
287                 if (doc == NULL) {
288                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
289                         return -1;
290                 }
291                 is_default_open = true;
292         } else {
293                 int retry_count = 0;
294
295                 while (NULL == doc) {
296                         doc = xmlParseFile(TTS_CONFIG);
297                         if (NULL != doc) {
298                                 break;
299                         }
300                         retry_count++;
301                         usleep(10000);
302
303                         if (TTS_RETRY_COUNT == retry_count) {
304                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
305                                 return -1;
306                         }
307                 }
308         }
309
310         cur = xmlDocGetRootElement(doc);
311         if (cur == NULL) {
312                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
313                 xmlFreeDoc(doc);
314                 return -1;
315         }
316
317         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
318                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
319                 xmlFreeDoc(doc);
320                 return -1;
321         }
322
323         cur = cur->xmlChildrenNode;
324         if (cur == NULL) {
325                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
326                 xmlFreeDoc(doc);
327                 return -1;
328         }
329
330         /* alloc engine info */
331         tts_config_s* temp;
332         temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
333         if (NULL == temp) {
334                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
335                 xmlFreeDoc(doc);
336                 return -1;
337         }
338
339         temp->engine_id = NULL;
340         temp->setting = NULL;
341         temp->language = NULL;
342
343         while (cur != NULL) {
344                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
345                         key = xmlNodeGetContent(cur);
346                         if (NULL != key) {
347                                 if (NULL != temp->engine_id)    free(temp->engine_id);
348                                 temp->engine_id = strdup((char*)key);
349                                 xmlFree(key);
350                         } else {
351                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine id is NULL");
352                         }
353                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
354                         key = xmlNodeGetContent(cur);
355                         if (NULL != key) {
356                                 if (NULL != temp->setting)      free(temp->setting);
357                                 temp->setting = strdup((char*)key);
358                                 xmlFree(key);
359                         } else {
360                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] setting path is NULL");
361                         }
362                         
363                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
364                         key = xmlNodeGetContent(cur);
365                         if (NULL != key) {
366                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
367                                         temp->auto_voice = true;
368                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
369                                         temp->auto_voice = false;
370                                 } else {
371                                         SLOG(LOG_ERROR, tts_tag(), "Auto voice is wrong");
372                                         temp->auto_voice = true;
373                                 }
374
375                                 xmlFree(key);
376                         } else {
377                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
378                         }
379                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
380                         key = xmlNodeGetContent(cur);
381                         if (NULL != key) {
382                                 if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
383                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
384                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
385                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
386                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
387                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
388                                 } else {
389                                         SLOG(LOG_WARN, tts_tag(), "Voice type is user defined");
390                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
391                                 }
392
393                                 xmlFree(key);
394                         } else {
395                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
396                         }
397                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
398                         key = xmlNodeGetContent(cur);
399                         if (NULL != key) {
400                                 if (NULL != temp->language)     free(temp->language);
401                                 temp->language = strdup((char*)key);
402                                 xmlFree(key);
403                         } else {
404                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine uuid is NULL");
405                         }
406
407                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
408                         key = xmlNodeGetContent(cur);
409                         if (NULL != key) {
410                                 temp->speech_rate = atoi((char*)key);
411                                 xmlFree(key);
412                         } else {
413                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] speech rate is NULL");
414                         }
415                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
416                         key = xmlNodeGetContent(cur);
417                         if (NULL != key) {
418                                 temp->pitch = atoi((char*)key);
419                                 xmlFree(key);
420                         } else {
421                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Pitch is NULL");
422                         }
423                 } else {
424
425                 }
426
427                 cur = cur->next;
428         }
429
430         *config_info = temp;
431         g_config_doc = doc;
432
433         if (true == is_default_open) {
434                 int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
435                 if (0 > ret) {
436                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
437                 }
438
439                 /* Set mode */
440                 if (0 > chmod(TTS_CONFIG, 0666)) {
441                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
442                 }
443
444                 /* Set owner */
445                 if (0 > chown(TTS_CONFIG, 5000, 5000)) {
446                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file owner : %d", ret);
447                 }
448                 SLOG(LOG_DEBUG, tts_tag(), "Default config is changed : pid(%d)", getpid());
449         }
450
451         return 0;
452 }
453
454 int tts_parser_unload_config(tts_config_s* config_info)
455 {
456         if (NULL != g_config_doc)       xmlFreeDoc(g_config_doc);
457         if (NULL != config_info) {
458                 if (NULL != config_info->engine_id)     free(config_info->engine_id);
459                 if (NULL != config_info->setting)       free(config_info->setting);
460                 if (NULL != config_info->language)      free(config_info->language);
461                 free(config_info);
462         }
463
464         return 0;
465 }
466
467 int tts_parser_set_engine(const char* engine_id, const char* setting, const char* language, int type)
468 {
469         if (NULL == engine_id) {
470                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
471                 return -1;
472         }
473
474         xmlNodePtr cur = NULL;
475         cur = xmlDocGetRootElement(g_config_doc);
476         if (cur == NULL) {
477                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
478                 return -1;
479         }
480
481         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
482                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
483                 return -1;
484         }
485
486         cur = cur->xmlChildrenNode;
487         if (cur == NULL) {
488                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
489                 return -1;
490         }
491
492         while (cur != NULL) {
493                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
494                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
495                 }
496
497                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
498                         xmlNodeSetContent(cur, (const xmlChar *)language);
499                 }
500
501                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
502                         xmlNodeSetContent(cur, (const xmlChar *)setting);
503                 }
504
505                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
506                         switch (type) {
507                         case TTS_CONFIG_VOICE_TYPE_MALE:        xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_MALE);        break;
508                         case TTS_CONFIG_VOICE_TYPE_FEMALE:      xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
509                         case TTS_CONFIG_VOICE_TYPE_CHILD:       xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_CHILD);       break;
510                         default:                                xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
511                         }
512                 }
513                 
514                 cur = cur->next;
515         }
516
517         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
518         if (0 > ret) {
519                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
520         }
521
522         return 0;
523 }
524
525 int tts_parser_set_voice(const char* language, int type)
526 {
527         if (NULL == language) {
528                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
529                 return -1;
530         }
531
532         xmlNodePtr cur = NULL;
533         cur = xmlDocGetRootElement(g_config_doc);
534         if (cur == NULL) {
535                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
536                 return -1;
537         }
538
539         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
540                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
541                 return -1;
542         }
543
544         cur = cur->xmlChildrenNode;
545         if (cur == NULL) {
546                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
547                 return -1;
548         }
549
550         while (cur != NULL) {
551                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
552                         xmlNodeSetContent(cur, (const xmlChar *)language);
553                 } 
554
555                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
556                         switch (type) {
557                         case TTS_CONFIG_VOICE_TYPE_MALE:        xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_MALE);        break;
558                         case TTS_CONFIG_VOICE_TYPE_FEMALE:      xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
559                         case TTS_CONFIG_VOICE_TYPE_CHILD:       xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_CHILD);       break;
560                         default:
561                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid type : %d", type);
562                                 xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);
563                                 break;
564                         }
565                 }
566
567                 cur = cur->next;
568         }
569
570         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
571         if (0 > ret) {
572                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
573         }
574
575         return 0;
576 }
577
578 int tts_parser_set_auto_voice(bool value)
579 {
580         xmlNodePtr cur = NULL;
581         cur = xmlDocGetRootElement(g_config_doc);
582         if (cur == NULL) {
583                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
584                 return -1;
585         }
586
587         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
588                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
589                 return -1;
590         }
591
592         cur = cur->xmlChildrenNode;
593         if (cur == NULL) {
594                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
595                 return -1;
596         }
597
598         while (cur != NULL) {
599                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
600                         if (true == value) {
601                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
602                         } else if (false == value) {
603                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
604                         } else {
605                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong value of auto voice");
606                                 return -1;
607                         }
608                         break;
609                 }
610                 cur = cur->next;
611         }
612
613         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
614         if (0 > ret) {
615                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
616         }
617
618         return 0;
619 }
620
621 int tts_parser_set_speech_rate(int value)
622 {
623         xmlNodePtr cur = NULL;
624         cur = xmlDocGetRootElement(g_config_doc);
625         if (cur == NULL) {
626                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
627                 return -1;
628         }
629
630         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
631                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
632                 return -1;
633         }
634
635         cur = cur->xmlChildrenNode;
636         if (cur == NULL) {
637                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
638                 return -1;
639         }
640
641         while (cur != NULL) {
642                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
643                         char temp[10];
644                         memset(temp, '\0', 10);
645                         snprintf(temp, 10, "%d", value);
646
647                         xmlNodeSetContent(cur, (const xmlChar *)temp);
648
649                         SLOG(LOG_DEBUG, tts_tag(), "Set speech rate : %s", temp);
650                         break;
651                 }
652
653                 cur = cur->next;
654         }
655
656         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
657         if (0 > ret) {
658                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
659         }
660
661         return 0;
662 }
663
664 int tts_parser_set_pitch(int value)
665 {
666         xmlNodePtr cur = NULL;
667         cur = xmlDocGetRootElement(g_config_doc);
668         if (cur == NULL) {
669                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
670                 return -1;
671         }
672
673         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
674                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
675                 return -1;
676         }
677
678         cur = cur->xmlChildrenNode;
679         if (cur == NULL) {
680                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
681                 return -1;
682         }
683
684         while (cur != NULL) {
685                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
686                         char temp[10];
687                         memset(temp, '\0', 10);
688                         snprintf(temp, 10, "%d", value);
689                         xmlNodeSetContent(cur, (const xmlChar *)temp);
690                         break;
691                 } 
692
693                 cur = cur->next;
694         }
695
696         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
697         if (0 > ret) {
698                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
699         }
700
701         return 0;
702 }
703
704 int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voice, char** language, int* voice_type, 
705                                    int* speech_rate, int* pitch)
706 {
707         if (NULL == engine || NULL == setting || NULL == language || NULL == voice_type || NULL == speech_rate) {
708                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
709                 return -1;
710         }
711
712         xmlDocPtr doc = NULL;
713         xmlNodePtr cur_new = NULL;
714         xmlNodePtr cur_old = NULL;
715
716         xmlChar *key_new;
717         xmlChar *key_old;
718
719         int retry_count = 0;
720         while (NULL == doc) {
721                 doc = xmlParseFile(TTS_CONFIG);
722                 if (NULL != doc) {
723                         break;
724                 }
725                 retry_count++;
726                 usleep(10000);
727
728                 if (TTS_RETRY_COUNT == retry_count) {
729                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
730                         return -1;
731                 }
732         }
733
734         cur_new = xmlDocGetRootElement(doc);
735         cur_old = xmlDocGetRootElement(g_config_doc);
736         if (cur_new == NULL || cur_old == NULL) {
737                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
738                 xmlFreeDoc(doc);
739                 return -1;
740         }
741
742         if (xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG) || 
743         xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
744                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
745                 xmlFreeDoc(doc);
746                 return -1;
747         }
748
749         cur_new = cur_new->xmlChildrenNode;
750         cur_old = cur_old->xmlChildrenNode;
751         if (cur_new == NULL || cur_old == NULL) {
752                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
753                 xmlFreeDoc(doc);
754                 return -1;
755         }
756
757         while (cur_new != NULL && cur_old != NULL) {
758                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
759                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
760                                 key_old = xmlNodeGetContent(cur_old);
761                                 if (NULL != key_old) {
762                                         key_new = xmlNodeGetContent(cur_new);
763                                         if (NULL != key_new) {
764                                                 if (0 != xmlStrcmp(key_old, key_new)) {
765                                                         SLOG(LOG_DEBUG, tts_tag(), "Old engine id(%s), New engine(%s)", 
766                                                                 (char*)key_old, (char*)key_new);
767                                                         if (NULL != *engine)    free(*engine);
768                                                         *engine = strdup((char*)key_new);
769                                                 }
770                                                 xmlFree(key_new);
771                                         }
772                                         xmlFree(key_old);
773                                 }
774                         } else {
775                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
776                         }
777                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
778                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
779                                 key_old = xmlNodeGetContent(cur_old);
780                                 if (NULL != key_old) {
781                                         key_new = xmlNodeGetContent(cur_new);
782                                         if (NULL != key_new) {
783                                                 if (0 != xmlStrcmp(key_old, key_new)) {
784                                                         SLOG(LOG_DEBUG, tts_tag(), "Old engine setting(%s), New engine setting(%s)", 
785                                                                 (char*)key_old, (char*)key_new);
786                                                         if (NULL != *setting)   free(*setting);
787                                                         *setting = strdup((char*)key_new);
788                                                 }
789                                                 xmlFree(key_new);
790                                         }
791                                         xmlFree(key_old);
792                                 }
793                         } else {
794                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
795                         }
796                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
797                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
798                                 key_old = xmlNodeGetContent(cur_old);
799                                 if (NULL != key_old) {
800                                         key_new = xmlNodeGetContent(cur_new);
801                                         if (NULL != key_new) {
802                                                 if (0 != xmlStrcmp(key_old, key_new)) {
803                                                         SLOG(LOG_DEBUG, tts_tag(), "Old auto voice (%s), New auto voice(%s)", 
804                                                                 (char*)key_old, (char*)key_new);
805                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
806                                                                 *auto_voice = true;
807                                                         } else {
808                                                                 *auto_voice = false;
809                                                         }
810                                                 }
811                                                 xmlFree(key_new);
812                                         }
813                                         xmlFree(key_old);
814                                 }
815                         } else {
816                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
817                         }
818                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
819                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
820                                 key_old = xmlNodeGetContent(cur_old);
821                                 if (NULL != key_old) {
822                                         key_new = xmlNodeGetContent(cur_new);
823                                         if (NULL != key_new) {
824                                                 if (0 != xmlStrcmp(key_old, key_new)) {
825                                                         SLOG(LOG_DEBUG, tts_tag(), "Old language(%s), New language(%s)", 
826                                                                 (char*)key_old, (char*)key_new);
827                                                         if (NULL != *language)  free(*language);
828                                                         *language = strdup((char*)key_new);
829                                                 }
830                                                 xmlFree(key_new);
831                                         }
832                                         xmlFree(key_old);
833                                 }
834                         } else {
835                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
836                         }
837                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
838                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
839                                 key_old = xmlNodeGetContent(cur_old);
840                                 if (NULL != key_old) {
841                                         key_new = xmlNodeGetContent(cur_new);
842                                         if (NULL != key_new) {
843                                                 if (0 != xmlStrcmp(key_old, key_new)) {
844                                                         SLOG(LOG_DEBUG, tts_tag(), "Old voice type(%s), New voice type(%s)", 
845                                                                 (char*)key_old, (char*)key_new);
846                                                         if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
847                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
848                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
849                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
850                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
851                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
852                                                         } else {
853                                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] New voice type is not valid");
854                                                         }
855                                                 }
856                                                 xmlFree(key_new);
857                                         }
858                                         xmlFree(key_old);
859                                 }
860                         } else {
861                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
862                         }
863                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
864                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
865                                 key_old = xmlNodeGetContent(cur_old);
866                                 if (NULL != key_old) {
867                                         key_new = xmlNodeGetContent(cur_new);
868                                         if (NULL != key_new) {
869                                                 if (0 != xmlStrcmp(key_old, key_new)) {
870                                                         SLOG(LOG_DEBUG, tts_tag(), "Old speech rate(%s), New speech rate(%s)", 
871                                                                 (char*)key_old, (char*)key_new);
872                                                         *speech_rate = atoi((char*)key_new);
873                                                 }
874                                                 xmlFree(key_new);
875                                         }
876                                         xmlFree(key_old);
877                                 }
878                         } else {
879                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
880                         }
881                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
882                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
883                                 key_old = xmlNodeGetContent(cur_old);
884                                 if (NULL != key_old) {
885                                         key_new = xmlNodeGetContent(cur_new);
886                                         if (NULL != key_new) {
887                                                 if (0 != xmlStrcmp(key_old, key_new)) {
888                                                         SLOG(LOG_DEBUG, tts_tag(), "Old pitch(%s), New pitch(%s)", 
889                                                                 (char*)key_old, (char*)key_new);
890                                                         *pitch = atoi((char*)key_new);
891                                                 }
892                                                 xmlFree(key_new);
893                                         }
894                                         xmlFree(key_old);
895                                 }
896                         } else {
897                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
898                         }
899                 } else {
900
901                 }
902
903                 cur_new = cur_new->next;
904                 cur_old = cur_old->next;
905         }
906         
907         xmlFreeDoc(g_config_doc);
908         g_config_doc = doc;
909
910         return 0;
911 }