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