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