82f84287fedc04c37d052f7c4ad026d9d271fd54
[platform/core/uifw/tts.git] / common / tts_config_parser.c
1 /*
2 *  Copyright (c) 2011-2016 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                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse xml file");
65                 return -1;
66         }
67
68         cur = xmlDocGetRootElement(doc);
69         if (cur == NULL) {
70                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
71                 xmlFreeDoc(doc);
72                 doc = NULL;
73                 return -1;
74         }
75
76         if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
77                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT 'tts-engine'");
78                 xmlFreeDoc(doc);
79                 doc = NULL;
80                 return -1;
81         }
82
83         cur = cur->xmlChildrenNode;
84         if (cur == NULL) {
85                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
86                 xmlFreeDoc(doc);
87                 doc = NULL;
88                 return -1;
89         }
90
91         /* alloc engine info */
92         tts_engine_info_s* temp;
93         temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
94         if (NULL == temp) {
95                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
96                 xmlFreeDoc(doc);
97                 doc = NULL;
98                 return -1;
99         }
100
101         temp->name = NULL;
102         temp->uuid = NULL;
103         temp->voices = NULL;
104         temp->setting = NULL;
105         temp->pitch_support = false;
106
107         while (cur != NULL) {
108                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
109                         key = xmlNodeGetContent(cur);
110                         if (NULL != key) {
111                                 if (NULL != temp->name) {
112                                         free(temp->name);
113                                         temp->name = NULL;
114                                 }
115                                 temp->name = strdup((char*)key);
116                                 xmlFree(key);
117                                 key = NULL;
118                         } else {
119                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
120                         }
121                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_ID)) {
122                         key = xmlNodeGetContent(cur);
123                         if (NULL != key) {
124                                 if (NULL != temp->uuid) {
125                                         free(temp->uuid);
126                                         temp->uuid = NULL;
127                                 }
128                                 temp->uuid = strdup((char*)key);
129                                 xmlFree(key);
130                                 key = NULL;
131                         } else {
132                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
133                         }
134                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_SETTING)) {
135                         key = xmlNodeGetContent(cur);
136                         if (NULL != key) {
137                                 if (NULL != temp->setting) {
138                                         free(temp->setting);
139                                         temp->setting = NULL;
140                                 }
141                                 temp->setting = strdup((char*)key);
142                                 xmlFree(key);
143                                 key = NULL;
144                         } else {
145                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
146                         }
147                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
148                         xmlNodePtr voice_node = NULL;
149                         voice_node = cur->xmlChildrenNode;
150
151                         while (NULL != voice_node) {
152                                 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
153                                         tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
154                                         if (NULL == temp_voice) {
155                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
156                                                 break;
157                                         }
158
159                                         attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
160                                         if (NULL != attr) {
161                                                 if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
162                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
163                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
164                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
165                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
166                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
167                                                 } else {
168                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
169                                                 }
170                                                 xmlFree(attr);
171                                                 attr = NULL;
172                                         } else {
173                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
174                                                 free(temp_voice);
175                                                 temp_voice = NULL;
176                                                 continue;
177                                         }
178
179                                         key = xmlNodeGetContent(voice_node);
180                                         if (NULL != key) {
181                                                 if (NULL != temp_voice->language) {
182                                                         free(temp_voice->language);
183                                                         temp_voice->language = NULL;
184                                                 }
185                                                 temp_voice->language = strdup((char*)key);
186                                                 xmlFree(key);
187                                                 key = NULL;
188                                                 temp->voices = g_slist_append(temp->voices, temp_voice);
189                                         } else {
190                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
191                                                 if (NULL != temp_voice) {
192                                                         free(temp_voice);
193                                                         temp_voice = NULL;
194                                                 }
195                                         }
196                                 }
197                                 voice_node = voice_node->next;
198                         }
199                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_PITCH_SUPPORT)) {
200                         key = xmlNodeGetContent(cur);
201                         if (NULL != key) {
202                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
203                                         temp->pitch_support = true;
204                                 }
205                                 xmlFree(key);
206                                 key = NULL;
207                         } else {
208                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
209                         }
210                 }
211                 cur = cur->next;
212         }
213
214         xmlFreeDoc(doc);
215         doc = NULL;
216
217         if (NULL == temp->name || NULL == temp->uuid) {
218                 /* Invalid engine */
219                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid engine : %s", path);
220                 tts_parser_free_engine_info(temp);
221                 return -1;
222         }
223
224         *engine_info = temp;
225
226         return 0;
227 }
228
229 int tts_parser_free_engine_info(tts_engine_info_s* engine_info)
230 {
231         if (NULL == engine_info) {
232                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
233                 return -1;
234         }
235
236         if (NULL != engine_info->name) {
237                 free(engine_info->name);
238                 engine_info->name = NULL;
239         }
240         if (NULL != engine_info->uuid) {
241                 free(engine_info->uuid);
242                 engine_info->uuid = NULL;
243         }
244         if (NULL != engine_info->setting) {
245                 free(engine_info->setting);
246                 engine_info->setting = NULL;
247         }
248
249         tts_config_voice_s *temp_voice;
250         temp_voice = g_slist_nth_data(engine_info->voices, 0);
251
252         while (NULL != temp_voice) {
253                 if (NULL != temp_voice) {
254                         if (NULL != temp_voice->language) {
255                                 free(temp_voice->language);
256                                 temp_voice->language = NULL;
257                         }
258                         engine_info->voices = g_slist_remove(engine_info->voices, temp_voice);
259                         free(temp_voice);
260                         temp_voice = NULL;
261                 }
262
263                 temp_voice = g_slist_nth_data(engine_info->voices, 0);
264         }
265
266         if (NULL != engine_info) {
267                 free(engine_info);
268                 engine_info = NULL;
269         }
270
271         return 0;
272 }
273
274 int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
275 {
276         if (NULL == engine_info) {
277                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
278                 return -1;
279         }
280
281         SLOG(LOG_DEBUG, tts_tag(), "== get engine info ==");
282         SLOG(LOG_DEBUG, tts_tag(), " name : %s", engine_info->name);
283         SLOG(LOG_DEBUG, tts_tag(), " id   : %s", engine_info->uuid);
284         if (NULL != engine_info->setting)
285                 SLOG(LOG_DEBUG, tts_tag(), " setting : %s", engine_info->setting);
286
287         SLOG(LOG_DEBUG, tts_tag(), " voices");
288         GSList *iter = NULL;
289         tts_config_voice_s *temp_voice;
290
291         if (g_slist_length(engine_info->voices) > 0) {
292                 /* Get a first item */
293                 iter = g_slist_nth(engine_info->voices, 0);
294
295                 int i = 1;
296                 while (NULL != iter) {
297                         /*Get handle data from list*/
298                         temp_voice = iter->data;
299
300                         SLOG(LOG_DEBUG, tts_tag(), "  [%dth] type(%d) lang(%s)", 
301                                 i, temp_voice->type, temp_voice->language);
302
303                         /*Get next item*/
304                         iter = g_slist_next(iter);
305                         i++;
306                 }
307         } else {
308                 SLOG(LOG_ERROR, tts_tag(), "  Voice is NONE");
309         }
310
311         SLOG(LOG_DEBUG, tts_tag(), "=====================");
312
313         return 0;
314 }
315
316 int tts_parser_load_config(tts_config_s** config_info)
317 {
318         if (NULL == config_info) {
319                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
320                 return -1;
321         }
322
323         xmlDocPtr doc = NULL;
324         xmlNodePtr cur = NULL;
325         xmlChar *key;
326         bool is_default_open = false;
327
328         /* For Thread safety */
329         xmlInitParser();
330
331         if (0 != access(TTS_CONFIG, F_OK)) {
332                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
333                 if (doc == NULL) {
334                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
335                         xmlCleanupParser();
336                         return -1;
337                 }
338                 is_default_open = true;
339         } else {
340                 int retry_count = 0;
341
342                 while (NULL == doc) {
343                         doc = xmlParseFile(TTS_CONFIG);
344                         if (NULL != doc) {
345                                 break;
346                         }
347                         retry_count++;
348                         usleep(10000);
349
350                         if (TTS_RETRY_COUNT == retry_count) {
351                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
352                                 xmlCleanupParser();
353                                 return -1;
354                         }
355                 }
356         }
357
358         cur = xmlDocGetRootElement(doc);
359         if (cur == NULL) {
360                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
361                 xmlFreeDoc(doc);
362                 doc = NULL;
363                 xmlCleanupParser();
364                 return -1;
365         }
366
367         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
368                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
369                 xmlFreeDoc(doc);
370                 doc = NULL;
371                 xmlCleanupParser();
372                 return -1;
373         }
374
375         cur = cur->xmlChildrenNode;
376         if (cur == NULL) {
377                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
378                 xmlFreeDoc(doc);
379                 doc = NULL;
380                 xmlCleanupParser();
381                 return -1;
382         }
383
384         /* alloc engine info */
385         tts_config_s* temp;
386         temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
387         if (NULL == temp) {
388                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
389                 xmlFreeDoc(doc);
390                 doc = NULL;
391                 xmlCleanupParser();
392                 return -1;
393         }
394
395         temp->engine_id = NULL;
396         temp->setting = NULL;
397         temp->language = NULL;
398
399         while (cur != NULL) {
400                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
401                         key = xmlNodeGetContent(cur);
402                         if (NULL != key) {
403                                 if (NULL != temp->engine_id) {
404                                         free(temp->engine_id);
405                                         temp->engine_id = NULL;
406                                 }
407                                 temp->engine_id = strdup((char*)key);
408                                 xmlFree(key);
409                                 key = NULL;
410                         } else {
411                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine id is NULL");
412                         }
413                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
414                         key = xmlNodeGetContent(cur);
415                         if (NULL != key) {
416                                 if (NULL != temp->setting) {
417                                         free(temp->setting);
418                                         temp->setting = NULL;
419                                 }
420                                 temp->setting = strdup((char*)key);
421                                 xmlFree(key);
422                                 key = NULL;
423                         } else {
424                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] setting path is NULL");
425                         }
426                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
427                         key = xmlNodeGetContent(cur);
428                         if (NULL != key) {
429                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
430                                         temp->auto_voice = true;
431                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
432                                         temp->auto_voice = false;
433                                 } else {
434                                         SLOG(LOG_ERROR, tts_tag(), "Auto voice is wrong");
435                                         temp->auto_voice = true;
436                                 }
437
438                                 xmlFree(key);
439                                 key = NULL;
440                         } else {
441                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
442                         }
443                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
444                         key = xmlNodeGetContent(cur);
445                         if (NULL != key) {
446                                 if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
447                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
448                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
449                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
450                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
451                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
452                                 } else {
453                                         SLOG(LOG_WARN, tts_tag(), "Voice type is user defined");
454                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
455                                 }
456
457                                 xmlFree(key);
458                                 key = NULL;
459                         } else {
460                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
461                         }
462                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
463                         key = xmlNodeGetContent(cur);
464                         if (NULL != key) {
465                                 if (NULL != temp->language) {
466                                         free(temp->language);
467                                         temp->language = NULL;
468                                 }
469                                 temp->language = strdup((char*)key);
470                                 xmlFree(key);
471                                 key = NULL;
472                         } else {
473                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine uuid is NULL");
474                         }
475
476                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
477                         key = xmlNodeGetContent(cur);
478                         if (NULL != key) {
479                                 temp->speech_rate = atoi((char*)key);
480                                 xmlFree(key);
481                         } else {
482                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] speech rate is NULL");
483                         }
484                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
485                         key = xmlNodeGetContent(cur);
486                         if (NULL != key) {
487                                 temp->pitch = atoi((char*)key);
488                                 xmlFree(key);
489                                 key = NULL;
490                         } else {
491                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Pitch is NULL");
492                         }
493                 } else {
494
495                 }
496
497                 cur = cur->next;
498         }
499
500         *config_info = temp;
501         g_config_doc = doc;
502
503         if (true == is_default_open) {
504                 int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
505                 if (0 > ret) {
506                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
507                 }
508
509                 /* Set mode */
510                 if (0 > chmod(TTS_CONFIG, 0666)) {
511                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
512                 }
513
514                 /* Set owner */
515                 if (0 > chown(TTS_CONFIG, 5000, 5000)) {
516                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file owner : %d", ret);
517                 }
518                 SLOG(LOG_DEBUG, tts_tag(), "Default config is changed : pid(%d)", getpid());
519         }
520
521         return 0;
522 }
523
524 int tts_parser_unload_config(tts_config_s* config_info)
525 {
526         if (NULL != g_config_doc) {
527                 xmlFreeDoc(g_config_doc);
528                 g_config_doc = NULL;
529         }
530         if (NULL != config_info) {
531                 if (NULL != config_info->engine_id)     {
532                         free(config_info->engine_id);
533                         config_info->engine_id = NULL;
534                 }
535                 if (NULL != config_info->setting) {
536                         free(config_info->setting);
537                         config_info->setting = NULL;
538                 }
539                 if (NULL != config_info->language) {
540                         free(config_info->language);
541                         config_info->language = NULL;
542                 }
543                 free(config_info);
544                 config_info = NULL;
545         }
546
547         xmlCleanupParser();
548
549         return 0;
550 }
551
552
553 int tts_parser_copy_xml(const char* original, const char* destination)
554 {
555         if (NULL == original || NULL == destination) {
556                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
557                 return -1;
558         }
559
560         xmlDocPtr doc = NULL;
561         doc = xmlParseFile(original);
562         if (doc == NULL) {
563                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", original);
564                 return -1;
565         }
566
567         int ret = xmlSaveFile(destination, doc);
568         if (0 > ret) {
569                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
570         }
571
572         /* Set mode */
573         if (0 > chmod(destination, 0666)) {
574                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
575         }
576
577         xmlFreeDoc(doc);
578         doc = NULL;
579         SLOG(LOG_DEBUG, tts_tag(), "[SUCCESS] Copying xml");
580
581         return 0;
582 }
583
584 int tts_parser_set_engine(const char* engine_id, const char* setting, const char* language, int type)
585 {
586         if (NULL == engine_id) {
587                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
588                 return -1;
589         }
590
591         xmlNodePtr cur = NULL;
592         cur = xmlDocGetRootElement(g_config_doc);
593         if (cur == NULL) {
594                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
595                 return -1;
596         }
597
598         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
599                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
600                 return -1;
601         }
602
603         cur = cur->xmlChildrenNode;
604         if (cur == NULL) {
605                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
606                 return -1;
607         }
608
609         while (cur != NULL) {
610                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
611                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
612                 }
613
614                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
615                         xmlNodeSetContent(cur, (const xmlChar *)language);
616                 }
617
618                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
619                         xmlNodeSetContent(cur, (const xmlChar *)setting);
620                 }
621
622                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
623                         switch (type) {
624                         case TTS_CONFIG_VOICE_TYPE_MALE:        xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_MALE);        break;
625                         case TTS_CONFIG_VOICE_TYPE_FEMALE:      xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
626                         case TTS_CONFIG_VOICE_TYPE_CHILD:       xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_CHILD);       break;
627                         default:                                xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
628                         }
629                 }
630
631                 cur = cur->next;
632         }
633
634         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
635         if (0 > ret) {
636                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
637         }
638
639         return 0;
640 }
641
642 int tts_parser_set_voice(const char* language, int type)
643 {
644         if (NULL == language) {
645                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
646                 return -1;
647         }
648
649         xmlNodePtr cur = NULL;
650         cur = xmlDocGetRootElement(g_config_doc);
651         if (cur == NULL) {
652                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
653                 return -1;
654         }
655
656         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
657                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
658                 return -1;
659         }
660
661         cur = cur->xmlChildrenNode;
662         if (cur == NULL) {
663                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
664                 return -1;
665         }
666
667         while (cur != NULL) {
668                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
669                         xmlNodeSetContent(cur, (const xmlChar *)language);
670                 } 
671
672                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
673                         switch (type) {
674                         case TTS_CONFIG_VOICE_TYPE_MALE:        xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_MALE);        break;
675                         case TTS_CONFIG_VOICE_TYPE_FEMALE:      xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
676                         case TTS_CONFIG_VOICE_TYPE_CHILD:       xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_CHILD);       break;
677                         default:
678                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid type : %d", type);
679                                 xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);
680                                 break;
681                         }
682                 }
683
684                 cur = cur->next;
685         }
686
687         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
688         if (0 > ret) {
689                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
690         }
691
692         return 0;
693 }
694
695 int tts_parser_set_auto_voice(bool value)
696 {
697         xmlNodePtr cur = NULL;
698         cur = xmlDocGetRootElement(g_config_doc);
699         if (cur == NULL) {
700                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
701                 return -1;
702         }
703
704         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
705                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
706                 return -1;
707         }
708
709         cur = cur->xmlChildrenNode;
710         if (cur == NULL) {
711                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
712                 return -1;
713         }
714
715         while (cur != NULL) {
716                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
717                         if (true == value) {
718                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
719                         } else if (false == value) {
720                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
721                         } else {
722                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong value of auto voice");
723                                 return -1;
724                         }
725                         break;
726                 }
727                 cur = cur->next;
728         }
729
730         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
731         if (0 > ret) {
732                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
733         }
734
735         return 0;
736 }
737
738 int tts_parser_set_speech_rate(int value)
739 {
740         xmlNodePtr cur = NULL;
741         cur = xmlDocGetRootElement(g_config_doc);
742         if (cur == NULL) {
743                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
744                 return -1;
745         }
746
747         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
748                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
749                 return -1;
750         }
751
752         cur = cur->xmlChildrenNode;
753         if (cur == NULL) {
754                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
755                 return -1;
756         }
757
758         while (cur != NULL) {
759                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
760                         char temp[10];
761                         memset(temp, '\0', 10);
762                         snprintf(temp, 10, "%d", value);
763
764                         xmlNodeSetContent(cur, (const xmlChar *)temp);
765
766                         SLOG(LOG_DEBUG, tts_tag(), "Set speech rate : %s", temp);
767                         break;
768                 }
769
770                 cur = cur->next;
771         }
772
773         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
774         if (0 > ret) {
775                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
776         }
777
778         return 0;
779 }
780
781 int tts_parser_set_pitch(int value)
782 {
783         xmlNodePtr cur = NULL;
784         cur = xmlDocGetRootElement(g_config_doc);
785         if (cur == NULL) {
786                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
787                 return -1;
788         }
789
790         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
791                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
792                 return -1;
793         }
794
795         cur = cur->xmlChildrenNode;
796         if (cur == NULL) {
797                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
798                 return -1;
799         }
800
801         while (cur != NULL) {
802                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
803                         char temp[10];
804                         memset(temp, '\0', 10);
805                         snprintf(temp, 10, "%d", value);
806                         xmlNodeSetContent(cur, (const xmlChar *)temp);
807                         break;
808                 } 
809
810                 cur = cur->next;
811         }
812
813         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
814         if (0 > ret) {
815                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
816         }
817
818         return 0;
819 }
820
821 int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voice, char** language, int* voice_type, 
822                                    int* speech_rate, int* pitch)
823 {
824         if (NULL == engine || NULL == setting || NULL == language || NULL == voice_type || NULL == speech_rate) {
825                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
826                 return -1;
827         }
828
829         xmlDocPtr doc = NULL;
830         xmlNodePtr cur_new = NULL;
831         xmlNodePtr cur_old = NULL;
832
833         xmlChar *key_new;
834         xmlChar *key_old;
835
836         int retry_count = 0;
837         while (NULL == doc) {
838                 doc = xmlParseFile(TTS_CONFIG);
839                 if (NULL != doc) {
840                         break;
841                 }
842                 retry_count++;
843                 usleep(10000);
844
845                 if (TTS_RETRY_COUNT == retry_count) {
846                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
847                         return -1;
848                 }
849         }
850
851         cur_new = xmlDocGetRootElement(doc);
852         cur_old = xmlDocGetRootElement(g_config_doc);
853         if (cur_new == NULL || cur_old == NULL) {
854                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
855                 xmlFreeDoc(doc);
856                 doc = NULL;
857                 return -1;
858         }
859
860         if (xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG) || 
861         xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
862                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
863                 xmlFreeDoc(doc);
864                 doc = NULL;
865                 return -1;
866         }
867
868         cur_new = cur_new->xmlChildrenNode;
869         cur_old = cur_old->xmlChildrenNode;
870         if (cur_new == NULL || cur_old == NULL) {
871                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
872                 xmlFreeDoc(doc);
873                 doc = NULL;
874                 return -1;
875         }
876
877         while (cur_new != NULL && cur_old != NULL) {
878                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
879                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
880                                 key_old = xmlNodeGetContent(cur_old);
881                                 if (NULL != key_old) {
882                                         key_new = xmlNodeGetContent(cur_new);
883                                         if (NULL != key_new) {
884                                                 if (0 != xmlStrcmp(key_old, key_new)) {
885                                                         SLOG(LOG_DEBUG, tts_tag(), "Old engine id(%s), New engine(%s)", 
886                                                                 (char*)key_old, (char*)key_new);
887                                                         if (NULL != *engine) {
888                                                                 free(*engine);
889                                                                 *engine = NULL;
890                                                         }
891                                                         *engine = strdup((char*)key_new);
892                                                 }
893                                                 xmlFree(key_new);
894                                                 key_new = NULL;
895                                         }
896                                         xmlFree(key_old);
897                                         key_old = NULL;
898                                 }
899                         } else {
900                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
901                         }
902                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
903                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
904                                 key_old = xmlNodeGetContent(cur_old);
905                                 if (NULL != key_old) {
906                                         key_new = xmlNodeGetContent(cur_new);
907                                         if (NULL != key_new) {
908                                                 if (0 != xmlStrcmp(key_old, key_new)) {
909                                                         SLOG(LOG_DEBUG, tts_tag(), "Old engine setting(%s), New engine setting(%s)", 
910                                                                 (char*)key_old, (char*)key_new);
911                                                         if (NULL != *setting) {
912                                                                 free(*setting);
913                                                                 *setting = NULL;
914                                                         }
915                                                         *setting = strdup((char*)key_new);
916                                                 }
917                                                 xmlFree(key_new);
918                                                 key_new = NULL;
919                                         }
920                                         xmlFree(key_old);
921                                         key_old = NULL;
922                                 }
923                         } else {
924                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
925                         }
926                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
927                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
928                                 key_old = xmlNodeGetContent(cur_old);
929                                 if (NULL != key_old) {
930                                         key_new = xmlNodeGetContent(cur_new);
931                                         if (NULL != key_new) {
932                                                 if (0 != xmlStrcmp(key_old, key_new)) {
933                                                         SLOG(LOG_DEBUG, tts_tag(), "Old auto voice (%s), New auto voice(%s)", 
934                                                                 (char*)key_old, (char*)key_new);
935                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
936                                                                 *auto_voice = true;
937                                                         } else {
938                                                                 *auto_voice = false;
939                                                         }
940                                                 }
941                                                 xmlFree(key_new);
942                                                 key_new = NULL;
943                                         }
944                                         xmlFree(key_old);
945                                         key_old = NULL;
946                                 }
947                         } else {
948                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
949                         }
950                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
951                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
952                                 key_old = xmlNodeGetContent(cur_old);
953                                 if (NULL != key_old) {
954                                         key_new = xmlNodeGetContent(cur_new);
955                                         if (NULL != key_new) {
956                                                 if (0 != xmlStrcmp(key_old, key_new)) {
957                                                         SLOG(LOG_DEBUG, tts_tag(), "Old language(%s), New language(%s)", 
958                                                                 (char*)key_old, (char*)key_new);
959                                                         if (NULL != *language) {
960                                                                 free(*language);
961                                                                 *language = NULL;
962                                                         }
963                                                         *language = strdup((char*)key_new);
964                                                 }
965                                                 xmlFree(key_new);
966                                                 key_new = NULL;
967                                         }
968                                         xmlFree(key_old);
969                                         key_old = NULL;
970                                 }
971                         } else {
972                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
973                         }
974                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
975                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
976                                 key_old = xmlNodeGetContent(cur_old);
977                                 if (NULL != key_old) {
978                                         key_new = xmlNodeGetContent(cur_new);
979                                         if (NULL != key_new) {
980                                                 if (0 != xmlStrcmp(key_old, key_new)) {
981                                                         SLOG(LOG_DEBUG, tts_tag(), "Old voice type(%s), New voice type(%s)", 
982                                                                 (char*)key_old, (char*)key_new);
983                                                         if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
984                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
985                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
986                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
987                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
988                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
989                                                         } else {
990                                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] New voice type is not valid");
991                                                         }
992                                                 }
993                                                 xmlFree(key_new);
994                                                 key_new = NULL;
995                                         }
996                                         xmlFree(key_old);
997                                         key_old = NULL;
998                                 }
999                         } else {
1000                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1001                         }
1002                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1003                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1004                                 key_old = xmlNodeGetContent(cur_old);
1005                                 if (NULL != key_old) {
1006                                         key_new = xmlNodeGetContent(cur_new);
1007                                         if (NULL != key_new) {
1008                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1009                                                         SLOG(LOG_DEBUG, tts_tag(), "Old speech rate(%s), New speech rate(%s)", 
1010                                                                 (char*)key_old, (char*)key_new);
1011                                                         *speech_rate = atoi((char*)key_new);
1012                                                 }
1013                                                 xmlFree(key_new);
1014                                                 key_new = NULL;
1015                                         }
1016                                         xmlFree(key_old);
1017                                         key_old = NULL;
1018                                 }
1019                         } else {
1020                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1021                         }
1022                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1023                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1024                                 key_old = xmlNodeGetContent(cur_old);
1025                                 if (NULL != key_old) {
1026                                         key_new = xmlNodeGetContent(cur_new);
1027                                         if (NULL != key_new) {
1028                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1029                                                         SLOG(LOG_DEBUG, tts_tag(), "Old pitch(%s), New pitch(%s)", 
1030                                                                 (char*)key_old, (char*)key_new);
1031                                                         *pitch = atoi((char*)key_new);
1032                                                 }
1033                                                 xmlFree(key_new);
1034                                                 key_new = NULL;
1035                                         }
1036                                         xmlFree(key_old);
1037                                         key_old = NULL;
1038                                 }
1039                         } else {
1040                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1041                         }
1042                 } else {
1043
1044                 }
1045
1046                 cur_new = cur_new->next;
1047                 cur_old = cur_old->next;
1048         }
1049
1050         if (NULL != g_config_doc) {
1051                 xmlFreeDoc(g_config_doc);
1052                 g_config_doc = NULL;
1053         }
1054         g_config_doc = doc;
1055
1056         return 0;
1057 }