common : config-parser : add functions reading config file 33/180333/3
authorKichan Kwon <k_c.kwon@samsung.com>
Mon, 28 May 2018 10:55:38 +0000 (19:55 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Thu, 2 Aug 2018 04:39:53 +0000 (13:39 +0900)
- Open/Close config file
- Read integer value(s)
- Foreach-key function in a group

Change-Id: I8f84af0d48ca2e3e1a4fcea0425ced418356cd4f
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
CMakeLists.txt
packaging/resourced-headless.spec
src/common/config-parser.c [new file with mode: 0644]
src/common/config-parser.h [new file with mode: 0644]

index 3a24d8f55a493b5e5980e503158d864bc482a89a..ad9916ca28802c2b7e5c366a2a6f7fd8fb100a06 100644 (file)
@@ -4,8 +4,10 @@ PROJECT(${PKGNAME})
 
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src)
+SET(CONFIG_DIR ${CMAKE_SOURCE_DIR}/cfg)
 
 ADD_DEFINITIONS("-DLIB_DIR=\"${LIB_DIR}\"")
+ADD_DEFINITIONS("-DCONFIG_INSTALL_DIR=\"${CONFIG_INSTALL_DIR}\"")
 
 # Set build flag
 SET(PKG_MODULES
@@ -54,6 +56,10 @@ MACRO(BUILD_MODULE TITLE DIR_NAME TYPE)
        ENDIF()
 ENDMACRO()
 
+MACRO(ADD_CONFIG TITLE)
+       INSTALL(FILES ${CONFIG_DIR}/${TITLE}.conf DESTINATION ${CONFIG_INSTALL_DIR})
+ENDMACRO()
+
 # Build modules
 SET(COMMON_LIBRARY "${PKGNAME}-common")
 BUILD_MODULE(${COMMON_LIBRARY} "common" "library")
index dd9d4d43e7c150abc0f53633cf950fa549393575..91cf9ff41c4a4eefa86590280ae481e2c0ab71e5 100644 (file)
@@ -12,6 +12,8 @@ Source102:  %{name}.conf
 %define proc_usage_module ON
 %define test_module    ON
 
+%define config_install_dir /etc/resourced
+
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(gio-2.0)
@@ -75,6 +77,7 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
        -DFULLVER=%{version}    \
        -DMAJORVER=${MAJORVER}  \
        -DLIB_DIR=%{_libdir}    \
+       -DCONFIG_INSTALL_DIR=%{config_install_dir}      \
        -DPROC_USAGE_MODULE=%{proc_usage_module}        \
        -DMEMORY_MODULE=%{memory_module}        \
        -DTEST_MODULE=%{test_module}    \
diff --git a/src/common/config-parser.c b/src/common/config-parser.c
new file mode 100644 (file)
index 0000000..f5d5ce0
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * resourced-headless
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#include <glib.h>
+
+#include "config-parser.h"
+#include "log.h"
+#include "macro.h"
+
+/**
+ * @brief  Config file list
+ * @details  Key(name), Value(GKeyFile)
+ */
+static GHashTable *config_parser_files;
+
+void config_parser_free_GKeyFile(gpointer data)
+{
+       g_key_file_unref((GKeyFile *)data);
+}
+
+API int config_parser_get_int(const char *name, const char *group, const char *key, int *value)
+{
+       GError *err = NULL;
+       GKeyFile *config_file = NULL;
+
+       config_file = (GKeyFile *)g_hash_table_lookup(config_parser_files, name);
+       if (!config_file) {
+               _E("Failed to find %s config file", name);
+               return -ENOENT;
+       }
+
+       *value = g_key_file_get_integer(config_file, group, key, &err);
+       if (!value) {
+               _E("Failed to find the value related with the key %s : %s",
+                               key, err ? err->message : NULL);
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+API int config_parser_get_int_list(const char *name, const char *group, const char *key, int **values, size_t *length)
+{
+       GError *err = NULL;
+       GKeyFile *config_file = NULL;
+
+       config_file = (GKeyFile *)g_hash_table_lookup(config_parser_files, name);
+       if (!config_file) {
+               _E("Failed to find %s config file", name);
+               return -ENOENT;
+       }
+
+       *values = g_key_file_get_integer_list(config_file, group, key, length, &err);
+       if (!values) {
+               _E("Failed to find the value related with the key %s : %s",
+                               key, err ? err->message : NULL);
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+API void config_parser_foreach(const char *name, const char *group, config_parser_foreach_func func)
+{
+       int i;
+       gsize len;
+       gchar *value;
+       GError *err = NULL;
+       GKeyFile *config_file = NULL;
+       gchar **key_list;
+
+       config_file = (GKeyFile *)g_hash_table_lookup(config_parser_files, name);
+       if (!config_file) {
+               _E("Failed to find %s config file. Foreach function will not launched", name);
+               return;
+       }
+
+       key_list = g_key_file_get_keys(config_file, group, &len, &err);
+       if (!key_list) {
+               _E("Failed to read the group %s (%s). Foreach function will not launched",
+                               group, err ? err->message : NULL);
+               return;
+       }
+
+       for (i = 0; i < len; i++) {
+               value = g_key_file_get_value(config_file, group, key_list[i], &err);
+               if (!value) {
+                       _E("Failed to find the value paired with %s. Skip it", key_list[i]);
+                       continue;
+               }
+
+               func(key_list[i], (const void *)value);
+               g_free(value);
+       }
+
+       g_strfreev(key_list);
+}
+
+API int config_parser_open(const char *name)
+{
+       GError *err = NULL;
+       GKeyFile *config_file = NULL;
+       char path[128];
+
+       if (!config_parser_files) {
+               config_parser_files = g_hash_table_new_full(g_str_hash, g_str_equal,
+                               g_free, config_parser_free_GKeyFile);
+               g_assert(config_parser_files);
+       } else if (g_hash_table_contains(config_parser_files, name)) {
+               _E("%s config file is already opened");
+               return -EEXIST;
+       }
+
+       snprintf(path, 128, "%s/%s.conf", CONFIG_INSTALL_DIR, name);
+
+       config_file = g_key_file_new();
+       g_assert(config_file);
+
+       if (!g_key_file_load_from_file(config_file, path, G_KEY_FILE_NONE, &err)) {
+               _E("Failed to load %s : %s", path, err ? err->message : NULL);
+               return -EIO;
+       }
+
+       g_hash_table_insert(config_parser_files, strndup(name, strlen(name) + 1), config_file);
+
+       return 0;
+}
+
+API void config_parser_close(const char *name)
+{
+       g_hash_table_remove(config_parser_files, name);
+}
diff --git a/src/common/config-parser.h b/src/common/config-parser.h
new file mode 100644 (file)
index 0000000..f8edd36
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * resourced-headless
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+/**
+ * @file  config-parser.h
+ * @brief  Parse config file
+ */
+
+#ifndef __RESOURCED_HEADLESS_CONFIG_PARSER_H__
+#define __RESOURCED_HEADLESS_CONFIG_PARSER_H__
+
+#define CONFIG_FILE_PATH(name) CONFIG_INSTALL_DIR"/"#name".conf"
+
+typedef void (*config_parser_foreach_func) (const char *key, const void *value);
+
+/**
+ * @brief  Find the matching integer value in the config file
+ * @param[in] name  Config file's name
+ * @param[in] group  A group name
+ * @param[in] key  A key
+ * @param[out] value  The integer value associated with @key
+ * @return  0 on success, otherwise a negative error value
+ */
+int config_parser_get_int(const char *name, const char *group, const char *key, int *value);
+
+/**
+ * @brief  Find the matching integer list in the config file
+ * @param[in] name  Config file's name
+ * @param[in] group  A group name
+ * @param[in] key  A key
+ * @param[out] values  The integer list associated with @key
+ * @param[out] length  The number of elements in @values
+ * @return  0 on success, otherwise a negative error value
+ * @notice  You should free @values when no longer needed
+ */
+int config_parser_get_int_list(const char *name, const char *group, const char *key, int **values, size_t *length);
+
+/**
+ * @brief  Call function with each key
+ * @param[in] name  Config file's name
+ * @param[in] group  A group name
+ * @param[in] func  Function to call with each key
+ */
+void config_parser_foreach(const char *name, const char *group, config_parser_foreach_func func);
+
+/**
+ * @brief  Open config file
+ * @param[in] name  Config file's name
+ * @return  0 on success, otherwise a negative error value
+ */
+int config_parser_open(const char *name);
+
+/**
+ * @brief  Close config file
+ * @param[in] name  Config file's name
+ */
+void config_parser_close(const char *name);
+
+#endif /* __RESOURCED_HEADLESS_CONFIG_PARSER_H__ */