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