diff --git a/core/dap_config.c b/core/dap_config.c index ce16186e088ae0768a2e9f413f86d7cd03738fe2..6e3c5944c691a30cefc1b8b3754a89928dbfd7ab 100644 --- a/core/dap_config.c +++ b/core/dap_config.c @@ -20,8 +20,13 @@ typedef struct dap_config_item{ bool data_bool; double data_double; int32_t data_int32; + struct { + char **data_str_array; + uint16_t array_length; + }; }; - UT_hash_handle hh;; + bool is_array; + UT_hash_handle hh; } dap_config_item_t; @@ -31,9 +36,7 @@ typedef struct dap_config_internal } dap_config_internal_t; #define DAP_CONFIG_INTERNAL(a) ( (dap_config_internal_t* ) a->_internal ) -char *s_configs_path = "/opt/dap/etc"; - - +static char *s_configs_path = "/opt/dap/etc"; /** @@ -61,6 +64,22 @@ void dap_config_deinit() } + +/** + * @brief get_array_length + * @param value + * @details internal function parse string and return array length + * @return + */ +static uint16_t get_array_length(const char* str) { + uint16_t array_length = 1; // by default if not find ',' + while (*str) { + if (*str == ',') + array_length++; + str++; + } + return array_length; +} /** * @brief dap_config_open * @param a_name @@ -179,6 +198,43 @@ dap_config_t * dap_config_open(const char * a_name) } log_it(L_DEBUG," Param '%s' = '%s'", l_param_name, l_param_value); if (l_section_current){ + + if (l_param_value[0] == '[') { + if(l_param_value[1] == ']') { + log_it(L_WARNING, "Empty array!"); + continue; + } + + // delete '[' and ']' + char* values = l_param_value + 1; + values[l_param_value_size-2] = 0; + + dap_config_item_t * l_item = DAP_NEW_Z(dap_config_item_t); + + strncpy(l_item->name,l_param_name,sizeof(l_item->name)); + l_item->item_next = l_section_current->childs; + l_item->is_array = true; + l_section_current->childs = l_item; + l_item->array_length = get_array_length(l_param_value); + l_item->data_str_array = (char**) malloc (sizeof(char*) * l_item->array_length); + + // parsing items in array + int j = 0; + char *token = strtok(values, ","); + while(token) { + + // trim token whitespace + if (isspace(token[0])) + token = token + 1; + if (isspace(token[strlen(token) - 1])) + token[strlen(token) - 1] = 0; + + l_item->data_str_array[j] = strdup(token); + token = strtok(NULL, ","); + j++; + } + + } dap_config_item_t * l_item = DAP_NEW_Z(dap_config_item_t); strncpy(l_item->name,l_param_name,sizeof(l_item->name)); @@ -204,6 +260,7 @@ dap_config_t * dap_config_open(const char * a_name) } } } + fclose(f); }else{ log_it(L_ERROR,"Can't open config file '%s' (%s)",l_config_path,strerror(errno)); } @@ -221,24 +278,33 @@ dap_config_t * dap_config_open(const char * a_name) void dap_config_close(dap_config_t * a_config) { dap_config_item_t * l_item = DAP_CONFIG_INTERNAL(a_config)->item_root ; - while(l_item){ + while(l_item) { dap_config_item_t * l_item_child = l_item->childs; DAP_CONFIG_INTERNAL(a_config)->item_root = l_item->item_next; - while( l_item_child ){ + while(l_item_child) { l_item->childs = l_item_child->item_next; - if(l_item_child->data_str) + if(l_item_child->is_array) { + for(int i = 0; i< l_item_child->array_length; i++) + free(l_item_child->data_str_array[i]); + free(l_item_child->data_str_array); + } else if (l_item_child->data_str) { DAP_DELETE(l_item_child->data_str); + } DAP_DELETE(l_item_child); l_item_child = l_item->childs; } - if( l_item->data_str ) + + if(l_item->data_str) { DAP_DELETE(l_item->data_str); + } DAP_DELETE(l_item); - l_item = DAP_CONFIG_INTERNAL(a_config)->item_root; } + free(a_config->_internal); + free(a_config); + } /** @@ -256,6 +322,31 @@ int32_t dap_config_get_item_int32(dap_config_t * a_config, const char * a_sectio return 0; } +/** + * @brief dap_config_get_item + * @param a_config + * @param a_section_path + * @param a_item_name + * @return + */ +static dap_config_item_t * dap_config_get_item(dap_config_t * a_config, const char * a_section_path, const char * a_item_name) +{ + dap_config_item_t * l_item_section = DAP_CONFIG_INTERNAL(a_config)->item_root ; + while(l_item_section){ + if (strcmp(l_item_section->name,a_section_path)==0){ + dap_config_item_t * l_item = l_item_section->childs; + while (l_item){ + if (strcmp(l_item->name,a_item_name)==0){ + return l_item; + } + l_item = l_item->item_next; + } + } + l_item_section = l_item_section->item_next; + } + return NULL; +} + /** * @brief dap_config_get_item_str @@ -266,9 +357,31 @@ int32_t dap_config_get_item_int32(dap_config_t * a_config, const char * a_sectio */ const char * dap_config_get_item_str(dap_config_t * a_config, const char * a_section_path, const char * a_item_name) { - return dap_config_get_item_str_default(a_config,a_section_path,a_item_name, NULL); + dap_config_item_t * item = dap_config_get_item(a_config, a_section_path, a_item_name); + if (item == NULL) + return NULL; + return item->data_str; +} + + +/** + * @brief dap_config_get_array_str + * @param a_config + * @param a_section_path + * @param a_item_name + * @return + */ +const char** dap_config_get_array_str(dap_config_t * a_config, const char * a_section_path, + const char * a_item_name, uint16_t * array_length) { + dap_config_item_t * item = dap_config_get_item(a_config, a_section_path, a_item_name); + if (item == NULL) + return NULL; + if (array_length != NULL) + *array_length = item->array_length; + return (const char**)item->data_str_array; } + /** * @brief dap_config_get_item_str_default * @param a_config diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3f5f5231db0a928138a467e4e3886d343fe59ed5..1ca8602b1a1484f9426a99515ea0117117442325 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 2.8) project(libdap-test) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + # Tell CMake to run moc when necessary: set(CMAKE_AUTOMOC ON) diff --git a/test/core/DapConfig_test.hpp b/test/core/DapConfig_test.hpp index 2c8077cd76d7d0b4759cf8634c115734e77e36ae..6cbc26a2f93f055f537f9d1a43ec6d62b35b05b1 100644 --- a/test/core/DapConfig_test.hpp +++ b/test/core/DapConfig_test.hpp @@ -1,13 +1,48 @@ #pragma once #include <QTest> +#include <QDebug> #include "dap_config.h" class DapConfigTest : public QObject { Q_OBJECT private: + const QByteArray testconfigName = "test_dap_config.cfg"; + const QByteArray configForTesting ="db_type=\"mongoDb\";\n" + "db_name=\"dapDb\";\n" + "db_path=\"mongodb://localhost/db\";\n" + "listen_address=\"127.0.0.1\";\n" + "TTL_session_key=600;\n" + "vpn_addr=\"10.0.0.0\";\n"; + QFile configFile; + // helper functions private slots: + void initTestCase() { + qDebug() << "initTestCase"; + configFile.setFileName(testconfigName); + if(!configFile.open(QIODevice::WriteOnly)) + { + qDebug() << "[DapConfigTest] Cant create testing config"; + QVERIFY(false); + } + configFile.write(configForTesting.data(), configForTesting.length()); + configFile.close(); + } + void dapConfigOpenFail() { + // by default search in /opt/dap/etc path QVERIFY(dap_config_open("RandomNeverExistName") == NULL); } + +// void initAndOpenConfig() { +// // init current dir path for config +// dap_config_init("."); +// dap_config_t * file = dap_config_open(testconfigName.data()); +// // dap_config_close(file); +// } + + void cleanupTestCase() { + qDebug() << "cleanupTestCase"; + configFile.remove(); + } };