Add to check RW config file and reset config info
[platform/core/uifw/tts.git] / common / tts_config_parser.c
old mode 100755 (executable)
new mode 100644 (file)
index f9f5f8d..fe31e24
@@ -29,6 +29,7 @@
 #define TTS_TAG_ENGINE_VOICE           "voice"
 #define TTS_TAG_ENGINE_VOICE_TYPE      "type"
 #define TTS_TAG_ENGINE_PITCH_SUPPORT   "pitch-support"
+#define TTS_TAG_ENGINE_TEXT_SIZE       "text-size"
 
 #define TTS_TAG_CONFIG_BASE_TAG                "tts-config"
 #define TTS_TAG_CONFIG_ENGINE_ID       "engine"
 #define TTS_TAG_VOICE_TYPE_MALE                "male"
 #define TTS_TAG_VOICE_TYPE_CHILD       "child"
 
+#define TTS_MAX_TEXT_SIZE      2000
 
 extern char* tts_tag();
 
 static xmlDocPtr g_config_doc = NULL;
+char g_engine_id[128] = {0,};
+char g_setting[128] = {0,};
+char g_language[128] = {0,};
 
 int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info)
 {
@@ -54,6 +59,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                return -1;
        }
 
+       bool isTextsize = false;
        xmlDocPtr doc = NULL;
        xmlNodePtr cur = NULL;
        xmlChar *key = NULL;
@@ -94,6 +100,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
        if (NULL == temp) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
@@ -102,6 +109,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
        temp->voices = NULL;
        temp->setting = NULL;
        temp->pitch_support = false;
+       temp->text_size = 0;
 
        while (cur != NULL) {
                if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
@@ -113,6 +121,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                }
                                temp->name = strdup((char*)key);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
                        }
@@ -125,6 +134,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                }
                                temp->uuid = strdup((char*)key);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
                        }
@@ -137,6 +147,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                }
                                temp->setting = strdup((char*)key);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
                        }
@@ -164,6 +175,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                                        temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
                                                }
                                                xmlFree(attr);
+                                               attr = NULL;
                                        } else {
                                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
                                                free(temp_voice);
@@ -179,6 +191,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                                }
                                                temp_voice->language = strdup((char*)key);
                                                xmlFree(key);
+                                               key = NULL;
                                                temp->voices = g_slist_append(temp->voices, temp_voice);
                                        } else {
                                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
@@ -201,14 +214,28 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
                        }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_TEXT_SIZE)) {
+                       isTextsize = true;
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               temp->text_size = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_INFO, tts_tag(), "[INFO] text size is unlimited.");
+                               temp->text_size = 0;
+                       }
                }
                cur = cur->next;
        }
 
+       if (false == isTextsize) {
+               temp->text_size = TTS_MAX_TEXT_SIZE;
+       }
+
        xmlFreeDoc(doc);
        doc = NULL;
 
-       if (NULL == temp->name || NULL == temp->uuid) {
+       if (NULL == temp->uuid) {
                /* Invalid engine */
                SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid engine : %s", path);
                tts_parser_free_engine_info(temp);
@@ -302,7 +329,7 @@ int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
                SLOG(LOG_ERROR, tts_tag(), "  Voice is NONE");
        }
 
-       SLOG(LOG_DEBUG, tts_tag(), "=====================");
+       SLOG(LOG_DEBUG, tts_tag(), "@@@");
 
        return 0;
 }
@@ -326,6 +353,7 @@ int tts_parser_load_config(tts_config_s** config_info)
                doc = xmlParseFile(TTS_DEFAULT_CONFIG);
                if (doc == NULL) {
                        SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
+                       xmlCleanupParser();
                        return -1;
                }
                is_default_open = true;
@@ -342,7 +370,14 @@ int tts_parser_load_config(tts_config_s** config_info)
 
                        if (TTS_RETRY_COUNT == retry_count) {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
-                               return -1;
+                               doc = xmlParseFile(TTS_DEFAULT_CONFIG);
+                               if (NULL == doc) {
+                                       SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
+                                       xmlCleanupParser();
+                                       return -1;
+                               }
+                               is_default_open = true;
+                               break;
                        }
                }
        }
@@ -352,6 +387,7 @@ int tts_parser_load_config(tts_config_s** config_info)
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
                doc = NULL;
+               xmlCleanupParser();
                return -1;
        }
 
@@ -359,6 +395,7 @@ int tts_parser_load_config(tts_config_s** config_info)
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
                xmlFreeDoc(doc);
                doc = NULL;
+               xmlCleanupParser();
                return -1;
        }
 
@@ -367,6 +404,7 @@ int tts_parser_load_config(tts_config_s** config_info)
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
                doc = NULL;
+               xmlCleanupParser();
                return -1;
        }
 
@@ -376,35 +414,35 @@ int tts_parser_load_config(tts_config_s** config_info)
        if (NULL == temp) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
                xmlFreeDoc(doc);
+               doc = NULL;
+               xmlCleanupParser();
                return -1;
        }
 
-       temp->engine_id = NULL;
-       temp->setting = NULL;
-       temp->language = NULL;
+       memset(g_engine_id, '\0', sizeof(g_engine_id));
+       memset(g_setting, '\0', sizeof(g_setting));
+       memset(g_language, '\0', sizeof(g_language));
+
+       temp->engine_id = g_engine_id;
+       temp->setting = g_setting;
+       temp->language = g_language;
 
        while (cur != NULL) {
                if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
                        key = xmlNodeGetContent(cur);
                        if (NULL != key) {
-                               if (NULL != temp->engine_id) {
-                                       free(temp->engine_id);
-                                       temp->engine_id = NULL;
-                               }
-                               temp->engine_id = strdup((char*)key);
+                               strncpy(temp->engine_id, (char*)key, sizeof(g_engine_id) - 1);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine id is NULL");
                        }
                } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
                        key = xmlNodeGetContent(cur);
                        if (NULL != key) {
-                               if (NULL != temp->setting) {
-                                       free(temp->setting);
-                                       temp->setting = NULL;
-                               }
-                               temp->setting = strdup((char*)key);
+                               strncpy(temp->setting, (char*)key, sizeof(g_setting) - 1);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] setting path is NULL");
                        }
@@ -421,6 +459,7 @@ int tts_parser_load_config(tts_config_s** config_info)
                                }
 
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
                        }
@@ -439,18 +478,16 @@ int tts_parser_load_config(tts_config_s** config_info)
                                }
 
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
                        }
                } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
                        key = xmlNodeGetContent(cur);
                        if (NULL != key) {
-                               if (NULL != temp->language) {
-                                       free(temp->language);
-                                       temp->language = NULL;
-                               }
-                               temp->language = strdup((char*)key);
+                               strncpy(temp->language, (char*)key, sizeof(g_language) - 1);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine uuid is NULL");
                        }
@@ -468,6 +505,7 @@ int tts_parser_load_config(tts_config_s** config_info)
                        if (NULL != key) {
                                temp->pitch = atoi((char*)key);
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Pitch is NULL");
                        }
@@ -482,13 +520,23 @@ int tts_parser_load_config(tts_config_s** config_info)
        g_config_doc = doc;
 
        if (true == is_default_open) {
-               int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
-               if (0 > ret) {
-                       SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
-               }
+               int retry_count = 0;
+               int ret = -1;
+               do {
+                       ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
+                       if (0 < ret)
+                               break;
+                       retry_count++;
+                       usleep(10000);
+
+                       if (TTS_RETRY_COUNT == retry_count) {
+                               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+                               return -1;
+                       }
+               } while (0 != ret);
 
                /* Set mode */
-               if (0 > chmod(TTS_CONFIG, 0666)) {
+               if (0 > chmod(TTS_CONFIG, 0600)) {
                        SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
                }
 
@@ -509,22 +557,12 @@ int tts_parser_unload_config(tts_config_s* config_info)
                g_config_doc = NULL;
        }
        if (NULL != config_info) {
-               if (NULL != config_info->engine_id)     {
-                       free(config_info->engine_id);
-                       config_info->engine_id = NULL;
-               }
-               if (NULL != config_info->setting) {
-                       free(config_info->setting);
-                       config_info->setting = NULL;
-               }
-               if (NULL != config_info->language) {
-                       free(config_info->language);
-                       config_info->language = NULL;
-               }
                free(config_info);
                config_info = NULL;
        }
 
+       xmlCleanupParser();
+
        return 0;
 }
 
@@ -546,14 +584,17 @@ int tts_parser_copy_xml(const char* original, const char* destination)
        int ret = xmlSaveFile(destination, doc);
        if (0 > ret) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", destination);
        }
 
        /* Set mode */
-       if (0 > chmod(destination, 0666)) {
+       if (0 > chmod(destination, 0600)) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
        }
 
        xmlFreeDoc(doc);
+       doc = NULL;
        SLOG(LOG_DEBUG, tts_tag(), "[SUCCESS] Copying xml");
 
        return 0;
@@ -605,13 +646,15 @@ int tts_parser_set_engine(const char* engine_id, const char* setting, const char
                        default:                                xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
                        }
                }
-               
+
                cur = cur->next;
        }
 
        int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
        if (0 > ret) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
        }
 
        return 0;
@@ -645,7 +688,7 @@ int tts_parser_set_voice(const char* language, int type)
        while (cur != NULL) {
                if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
                        xmlNodeSetContent(cur, (const xmlChar *)language);
-               } 
+               }
 
                if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
                        switch (type) {
@@ -665,6 +708,8 @@ int tts_parser_set_voice(const char* language, int type)
        int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
        if (0 > ret) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
        }
 
        return 0;
@@ -708,6 +753,8 @@ int tts_parser_set_auto_voice(bool value)
        int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
        if (0 > ret) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
        }
 
        return 0;
@@ -751,6 +798,8 @@ int tts_parser_set_speech_rate(int value)
        int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
        if (0 > ret) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
        }
 
        return 0;
@@ -783,7 +832,7 @@ int tts_parser_set_pitch(int value)
                        snprintf(temp, 10, "%d", value);
                        xmlNodeSetContent(cur, (const xmlChar *)temp);
                        break;
-               } 
+               }
 
                cur = cur->next;
        }
@@ -791,6 +840,8 @@ int tts_parser_set_pitch(int value)
        int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
        if (0 > ret) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
        }
 
        return 0;
@@ -869,8 +920,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        *engine = strdup((char*)key_new);
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -891,8 +944,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        *setting = strdup((char*)key_new);
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -913,8 +968,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        }
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -935,8 +992,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        *language = strdup((char*)key_new);
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -961,8 +1020,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        }
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -979,8 +1040,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        *speech_rate = atoi((char*)key_new);
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -997,8 +1060,10 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                                                        *pitch = atoi((char*)key_new);
                                                }
                                                xmlFree(key_new);
+                                               key_new = NULL;
                                        }
                                        xmlFree(key_old);
+                                       key_old = NULL;
                                }
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
@@ -1019,3 +1084,26 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
 
        return 0;
 }
+
+int tts_parser_reset()
+{
+       SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Reset g_config_doc as %s", TTS_DEFAULT_CONFIG);
+
+       if (NULL != g_config_doc) {
+               xmlFreeDoc(g_config_doc);
+               g_config_doc = NULL;
+       }
+
+       g_config_doc = xmlParseFile(TTS_DEFAULT_CONFIG);
+       if (NULL == g_config_doc) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse %s", TTS_DEFAULT_CONFIG);
+               return -1;
+       }
+
+       int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
+       if (0 > ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to save %s", TTS_CONFIG);
+       }
+
+       return 0;
+}