From ea67e1338f81537f601e29d80a04153fab768483 Mon Sep 17 00:00:00 2001 From: Lukasz Stanislawski Date: Fri, 14 Sep 2018 16:59:03 +0200 Subject: [PATCH] config module implementation config is thin wrapper around glib's g_key_file which provides generic storage for primitive types. Change-Id: Ic782dd30ff62b9c917bf91fa952e062e6f87b112 --- .gitignore | 1 + CMakeLists.txt | 1 + inc/config.h | 160 +++++++++++++++++++++++++++++++++++++++ src/config.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 395 insertions(+) create mode 100644 inc/config.h create mode 100644 src/config.c diff --git a/.gitignore b/.gitignore index 9b2402b..875c80c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .package-stamp .sign/ SA_Report +/res/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 95c94d6..fea0e79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") INCLUDE_DIRECTORIES(${PROJECT_ROOT_DIR}/inc) ADD_EXECUTABLE(${PROJECT_NAME} + ${PROJECT_ROOT_DIR}/src/config.c ${PROJECT_ROOT_DIR}/src/app.c ${PROJECT_ROOT_DIR}/src/log.c ${PROJECT_ROOT_DIR}/src/connection_manager.c diff --git a/inc/config.h b/inc/config.h new file mode 100644 index 0000000..735b754 --- /dev/null +++ b/inc/config.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +/** + * @brief Initializes config module. + * + * @return 0 on success, other value on error. + * + * @note config module reads/writes configuration stored in + * application's "data" directory in "config.ini" file. + */ +int config_init(); + +/** + * @brief Flush config to disk. + * + * @return 0 on success, other value on error. + */ +int config_save(); + +/** + * @brief Shutdowns config module. + */ +void config_shutdown(); + +/** + * @brief Get string value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[out] out value stored in configuration for given group and key. + * + * @return 0 on success, other if value for given group with key do not exist. + * + * @note @config_init should be called before using this function + * @note @out should be released with @free + */ +int config_get_string(const char *group, const char *key, char **out); + +/** + * @brief Sets string value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[in] value to be stored in configuration for given group and key. + * + * @note @config_init should be called before using this function + */ +void config_set_string(const char *group, const char *key, const char *value); + +/** + * @brief Get integer value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[out] out value stored in configuration for given group and key. + * + * @return 0 on success, other if value for given group with key do not exist. + * + * @note @config_init should be called before using this function + */ +int config_get_int(const char *group, const char *key, int *out); + +/** + * @brief Set integer value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[in] value to be stored in configuration for given group and key. + * + * @note @config_init should be called before using this function + */ +void config_set_int(const char *group, const char *key, int value); + +/** + * @brief Get double value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[out] out value stored in configuration for given group and key. + * + * @return 0 on success, other if value for given group with key do not exist. + * + * @note @config_init should be called before using this function + */ +int config_get_double(const char *group, const char *key, double *out); + +/** + * @brief Set double value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[in] value to be stored in configuration for given group and key. + * + * @note @config_init should be called before using this function + */ +void config_set_double(const char *group, const char *key, double value); + +/** + * @brief Get boolean value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[out] out value stored in configuration for given group and key. + * + * @return 0 on success, other if value for given group with key do not exist. + * + * @note @config_init should be called before using this function + */ +int config_get_bool(const char *group, const char *key, bool *out); + +/** + * @brief Set boolean value + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * @param[in] value to be stored in configuration for given group and key. + * + * @note @config_init should be called before using this function + */ +void config_set_bool(const char *group, const char *key, bool value); + +/** + * @brief Remove key from config. + * + * @param[in] group configuration group to which @key belongs + * @param[in] key configuration key name. + * + * @note @config_init should be called before using this function + */ +int config_remove_key(const char *group, const char *key); + +/** + * @brief Remove group from config. Removes all keys assigned to this group. + * + * @param[in] group configuration group name. + * + * @note @config_init should be called before using this function + */ +int config_remove_group(const char *group); + +#endif /* end of include guard: CONFIG_H */ diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..f9c16c7 --- /dev/null +++ b/src/config.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include "config.h" +#include "log.h" + +#include +#include +#include +#include + +#define CONFIG_FILENAME "config.ini" + +static GKeyFile *gk = NULL; + +static char *_config_file_path_get() +{ + char *ret = NULL; + char *data = app_get_data_path(); + + if (!data) + return NULL; + + if (asprintf(&ret, "%s%s", data, CONFIG_FILENAME) == -1) { + ret = NULL; + } + + free(data); + return ret; +} + +int config_init() +{ + GError *error = NULL; + + if (gk) { + _D("config_init already called."); + return 0; + } + + gk = g_key_file_new(); + if (!gk) { + _E("g_key_file_new failed."); + return -1; + } + + char *path = _config_file_path_get(); + + if (!g_key_file_load_from_file(gk, path, G_KEY_FILE_NONE, &error)) { + if (error->code != G_FILE_ERROR_NOENT) { + _E("g_key_file_load_from_file failed. %s", error->message); + g_key_file_free(gk); + g_error_free(error); + free(path); + return -1; + } + g_error_free(error); + } + + free(path); + return 0; +} + +int config_save() +{ + GError *error = NULL; + + retv_if(!gk, -1); + + char *path = _config_file_path_get(); + + if (!g_key_file_save_to_file(gk, path, &error)) { + _E("g_key_file_save_to_file failed: %s", error->message); + g_error_free(error); + free(path); + return -1; + } + free(path); + return 0; +} + +void config_shutdown() +{ + if (gk) g_key_file_free(gk); + gk = NULL; +} + +int config_get_string(const char *group, const char *key, char **out) +{ + GError *error = NULL; + char *value; + + retv_if(!gk, -1); + retv_if(!group, -1); + retv_if(!key, -1); + retv_if(!out, -1); + + value = g_key_file_get_string(gk, group, key, &error); + if (error) { + _E("g_key_file_get_string failed: %s", error->message); + g_error_free(error); + return -1; + } + *out = value; + return 0; +} + +void config_set_string(const char *group, const char *key, const char *value) +{ + ret_if(!gk); + ret_if(!group); + ret_if(!key); + + g_key_file_set_string(gk, group, key, value); +} + +int config_get_int(const char *group, const char *key, int *out) +{ + GError *error = NULL; + int value; + + retv_if(!gk, -1); + retv_if(!group, -1); + retv_if(!key, -1); + retv_if(!out, -1); + + value = g_key_file_get_integer(gk, group, key, &error); + if (error) { + _E("g_key_file_get_integer failed: %s", error->message); + g_error_free(error); + return -1; + } + *out = value; + return 0; +} + +void config_set_int(const char *group, const char *key, int value) +{ + ret_if(!gk); + ret_if(!group); + ret_if(!key); + + g_key_file_set_integer(gk, group, key, value); +} + +int config_get_double(const char *group, const char *key, double *out) +{ + GError *error = NULL; + double value; + + retv_if(!gk, -1); + retv_if(!group, -1); + retv_if(!key, -1); + retv_if(!out, -1); + + value = g_key_file_get_double(gk, group, key, &error); + if (error) { + _E("g_key_file_get_double failed: %s", error->message); + g_error_free(error); + return -1; + } + *out = value; + return 0; +} + +void config_set_double(const char *group, const char *key, double value) +{ + ret_if(!gk); + ret_if(!group); + ret_if(!key); + + g_key_file_set_double(gk, group, key, value); +} + +int config_get_bool(const char *group, const char *key, bool *out) +{ + GError *error = NULL; + bool value; + + retv_if(!gk, -1); + retv_if(!group, -1); + retv_if(!key, -1); + retv_if(!out, -1); + + value = g_key_file_get_boolean(gk, group, key, &error); + if (error) { + _E("g_key_file_get_boolean failed: %s", error->message); + g_error_free(error); + return -1; + } + *out = value; + return 0; +} + +void config_set_bool(const char *group, const char *key, bool value) +{ + ret_if(!gk); + ret_if(!group); + ret_if(!key); + + g_key_file_set_boolean(gk, group, key, value); +} + +int config_remove_key(const char *group, const char *key) +{ + retv_if(!gk, -1); + retv_if(!group, -1); + retv_if(!key, -1); + + return g_key_file_remove_key(gk, group, key, NULL) ? 0 : 1; +} + +int config_remove_group(const char *group) +{ + retv_if(!gk, -1); + retv_if(!group, -1); + + return g_key_file_remove_group(gk, group, NULL) ? 0 : 1; +} -- 2.7.4