From 1b66d5edabe19608575a3c8b64833725594d909b Mon Sep 17 00:00:00 2001 From: Max <51083570+DRdrProfessor@users.noreply.github.com> Date: Wed, 27 Dec 2023 13:41:42 +0100 Subject: [PATCH] Base - Adding properties to config implemented. --- src/net/CMakeLists.txt | 2 + src/net/configuration.c | 49 +++++++++++++++++- src/net/include/CMakeLists.txt | 4 +- src/net/include/config.h | 13 +++++ src/net/include/strutil.h | 15 ++++++ src/net/str/CMakeLists.txt | 4 ++ src/net/str/str_utils.c | 90 ++++++++++++++++++++++++++++++++++ src/server/server.c | 13 +++++ 8 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 src/net/include/config.h create mode 100644 src/net/include/strutil.h create mode 100644 src/net/str/CMakeLists.txt create mode 100644 src/net/str/str_utils.c diff --git a/src/net/CMakeLists.txt b/src/net/CMakeLists.txt index a25f239..66cf8a1 100644 --- a/src/net/CMakeLists.txt +++ b/src/net/CMakeLists.txt @@ -12,3 +12,5 @@ target_link_libraries(netex json-c) target_include_directories(netex PRIVATE ${CMAKE_SOURCE_DIR}/src/net/include) +add_subdirectory(include) +add_subdirectory(str) diff --git a/src/net/configuration.c b/src/net/configuration.c index 4bc76eb..b8a564c 100644 --- a/src/net/configuration.c +++ b/src/net/configuration.c @@ -1,8 +1,55 @@ +#include + +#include "config.h" #include "netex.h" +#include "strutil.h" -void config_set(const char* key, const char* value) +#define SEPARATOR_CHAR '.' + + +int config_set(CONFIGURATION* config, const char* key, const char* value) { + if (config == NULL) + { + WARN("Parameter 'config' is NULL!"); + return -1; + } + SPLIT_STR* splitted_key = splstr(key, '.'); + if (splitted_key == NULL || splitted_key->count == 0) + return -1; + if (config->json == NULL) + config->json = json_object_new_object(); + json_object* temp_obj = NULL; + for (int i = 0; i != splitted_key->count; i++) + { + json_object* current_obj; + if (temp_obj == NULL) + current_obj = config->json; + else + current_obj = temp_obj; + // If object with the key already exists, set the temp variable to the found object and continue the loop. (The found object will be used next time in the loop.) + if (json_object_object_get_ex(current_obj, splitted_key->delimited[i], &temp_obj)) + continue; + + if (i == splitted_key->count - 1) // Last key (set value) + { + json_object* value_object = json_object_new_string(value); + if (json_object_object_add(current_obj, splitted_key->delimited[i], value_object) != 0) + ERROR("Failed to set value '%s'", value); + break; + } + + json_object* new_json = json_object_new_object(); + if (json_object_object_add(current_obj, splitted_key->delimited[i], new_json) != 0) + { + ERROR("Failed to set new JSON object!"); + break; + } + temp_obj = new_json; + } + strsplfree(splitted_key); + return 0; } char* config_get(const char* key) diff --git a/src/net/include/CMakeLists.txt b/src/net/include/CMakeLists.txt index 180d4c3..c867edb 100644 --- a/src/net/include/CMakeLists.txt +++ b/src/net/include/CMakeLists.txt @@ -1,7 +1,9 @@ # libnet include target_sources(netex PUBLIC + "config.h" "net.h" "netex.h" "sockets.h" - "storage.h") \ No newline at end of file + "storage.h" + "strutil.h") \ No newline at end of file diff --git a/src/net/include/config.h b/src/net/include/config.h new file mode 100644 index 0000000..e15ed24 --- /dev/null +++ b/src/net/include/config.h @@ -0,0 +1,13 @@ +#ifndef CONFIG_H +#define CONFIG_H +#include + +typedef struct config_container +{ + json_object* json; + int has_allocations : 1; +} CONFIGURATION; + +int config_set(CONFIGURATION* config, const char* key, const char* value); + +#endif //CONFIG_H diff --git a/src/net/include/strutil.h b/src/net/include/strutil.h new file mode 100644 index 0000000..f444c7d --- /dev/null +++ b/src/net/include/strutil.h @@ -0,0 +1,15 @@ +#ifndef STRUTIL_H +#define STRUTIL_H + +typedef struct str_split +{ + char** delimited; + int count; +} SPLIT_STR; + +SPLIT_STR* splstr(const char* str, const char delimiter); +void strsplfree(SPLIT_STR* str); +size_t strocc(const char* str, const char character); +int str_token_count(const char* str, const char delimiter); + +#endif //STRUTIL_H diff --git a/src/net/str/CMakeLists.txt b/src/net/str/CMakeLists.txt new file mode 100644 index 0000000..921ddf2 --- /dev/null +++ b/src/net/str/CMakeLists.txt @@ -0,0 +1,4 @@ +# str source dir + +target_sources(netex PRIVATE + "str_utils.c") \ No newline at end of file diff --git a/src/net/str/str_utils.c b/src/net/str/str_utils.c new file mode 100644 index 0000000..bdd8849 --- /dev/null +++ b/src/net/str/str_utils.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include "strutil.h" +#include "netex.h" + +// String will be duplicated (allocated) and need to be freed with the 'strsplfree' function +SPLIT_STR* splstr(const char* str, const char delimiter) +{ + char* dup = strdup(str); + if (dup == NULL) + { + const int error = errno; + ERROR("Failed to duplicate string, error code: %i", error); + return NULL; + } + const size_t delim_occ = str_token_count(str, delimiter); + SPLIT_STR* splitted = malloc(sizeof(SPLIT_STR)); + if (splitted == NULL) + { + const int error = errno; + ERROR("Failed to allocate memory, error code: %i", error); + return NULL; + } + if (delim_occ != 0) + { + splitted->count = delim_occ; + splitted->delimited = malloc(splitted->count * sizeof(char*)); + if (splitted->delimited == NULL) + { + const int error = errno; + ERROR("Allocation failed, error code: %i", error); + free(splitted); + return NULL; + } + } + char delim[2] = "\0"; + delim[0] = delimiter; + char* token = strtok(dup, delim); + for (int i = 0; ; i++) + { + if (i != 0) + token = strtok(NULL, delim); + if (token == NULL) + break; + splitted->delimited[i] = token; + } + return splitted; +} + +void strsplfree(SPLIT_STR* str) +{ + free(str->delimited); + free(str); +} + +// Returns the amount of times the 'character' occurrs in the given string. +size_t strocc(const char* str, const char character) +{ + size_t occurrences = 0; + for (int i = 0;; i++) + { + if (str[i] == '\0') + break; + if (str[i] == character) + occurrences++; + } + return occurrences; +} +// Get the token count if it where to get tokenized (strtok) with the given delimiter. +int str_token_count(const char* str, const char delimiter) +{ + int path_elements = 1; + for (int i = 0;; i++) + { + if (str[i] == '\0') + { + if (i == 0) + break; + return path_elements; + } + if (str[i] == delimiter) + { + if (str[i + 1] == delimiter || str[i + 1] == '\0' || i == 0) + return -1; + path_elements++; + } + } + return -1; +} \ No newline at end of file diff --git a/src/server/server.c b/src/server/server.c index 4fb9443..4533393 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -1,10 +1,23 @@ #include #include "netex.h" +#include "config.h" int srv_setup(void); int main(int argc, char *argv[]) { + CONFIGURATION configuration; + config_set(&configuration, "Server.Connection.Port", "6920"); + config_set(&configuration, "Server.Connection.IP", "localhost"); + config_set(&configuration, "Global.Project.Name", "NetEx"); + config_set(&configuration, "Global.Project.Lang", "C"); + config_set(&configuration, "Global.Project.OS", "Linux"); + config_set(&configuration, "Server.Connection.db", "SQLite"); + PRINT_LINE("JSON:\n%s", json_object_to_json_string_ext(configuration.json, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY)); + + /*config_set("Server.Test", "Test value for server config"); + config_set("Server.port", "6920");*/ + netex_init(); PRINT_LINE("Hello, server!"); if (argc > 1)