/* * 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. */ #include #include #include #include #include "json-schema-defs.h" #include "config-deserializer.h" #include "config.h" #include "err-check.h" #include "log.h" static JsonNode *parse_string(JsonParser *parser, const char *config_json); static void config_array_iterate_func(JsonArray *array, guint index, JsonNode *element, gpointer user_data); static int calculate_task_counter(int frequency); static config_top_subject_e config_parse_top_subject(const char *option); static config_data_process_t config_parse_process_data(JsonArray *obj); static struct _cfg_data { int total_duration; int task_counter; } cfg_data = { .total_duration = 0, .task_counter = 0 }; config_t *deserialize_configs(const char *config_json, int *size, int *task_counter) { JsonParser *parser = json_parser_new(); JsonNode *root = parse_string(parser, config_json); JsonObject *obj = json_node_get_object(root); cfg_data.total_duration = json_object_get_int_member(obj, SCHEMA_CONFIG_TOTAL_DURATION); JsonArray *array = json_object_get_array_member(obj, SCHEMA_CONFIG_ENTRY); if (!array) { ERR("Json config is invalid!"); g_object_unref(parser); return NULL; } *size = json_array_get_length(array); config_t *configs = g_malloc(*size * sizeof(config_t)); json_array_foreach_element(array, config_array_iterate_func, configs); g_object_unref(parser); *task_counter = cfg_data.task_counter; return configs; } static JsonNode *parse_string(JsonParser *parser, const char *config_json) { GError *err = NULL; if (!json_parser_load_from_data(parser, config_json, -1, &err)) { ERR("Function \"json_parser_load_from_data()\" failed with message ", err->message); g_error_free(err); return NULL; } return json_parser_get_root(parser); } static void config_array_iterate_func(JsonArray *array, guint index, JsonNode *element, gpointer user_data) { config_t *configs = (config_t *)user_data; JsonObject *entry = json_node_get_object(element); const gchar *type = json_object_get_string_member(entry, SCHEMA_TYPE); gint64 frequency = json_object_get_int_member(entry, SCHEMA_FREQUENCY); configs[index].frequency = frequency; int c = calculate_task_counter(frequency); cfg_data.task_counter += c; if (g_strcmp0(type, SCHEMA_TYPE_TOP) == 0) { configs[index].scope = TOP; const gchar *subject = json_object_get_string_member(entry, SCHEMA_SUBJECT); configs[index].data.top.subject = config_parse_top_subject(subject); gint64 top = json_object_get_int_member(entry, SCHEMA_TOP); configs[index].data.top.top = top; } else if (g_strcmp0(type, SCHEMA_TYPE_SYSTEM) == 0) { configs[index].scope = SYSTEM; } else if (g_strcmp0(type, SCHEMA_TYPE_PROCESS) == 0) { configs[index].scope = PROCESS; configs[index].data.process = config_parse_process_data(json_object_get_array_member(entry, SCHEMA_REQUEST_DATA_FILTERS)); } else if (g_strcmp0(type, SCHEMA_TYPE_LOAD_AVG) == 0) { configs[index].scope = LOAD_AVG; } } static const char *json_object_safe_get_string_member(JsonObject *obj, const char *member) { if (json_object_has_member(obj, member)) return json_object_get_string_member(obj, member); return NULL; } static void _process_foreach_filter(JsonArray *array, guint index, JsonNode *node, gpointer user_data) { config_data_process_t *ret = user_data; struct filter filter; JsonObject *elem = json_node_get_object(node); if (!elem) return; const char *appid = json_object_safe_get_string_member(elem, SCHEMA_RESULT_APP_ID); const char *exe = json_object_safe_get_string_member(elem, SCHEMA_RESULT_EXE); filter.app_id = appid ? strdup(appid) : NULL; filter.exe = exe ? strdup(exe) : NULL; ret->filters[ret->n_filters++] = filter; } static config_data_process_t config_parse_process_data(JsonArray *array) { config_data_process_t ret = {0,}; int len = json_array_get_length(array); if (len == 0) return ret; ret.filters = calloc(len, sizeof(struct filter)); ret.n_filters = 0; json_array_foreach_element(array, _process_foreach_filter, &ret); return ret; } static int calculate_task_counter(int frequency) { return cfg_data.total_duration / frequency; } static config_top_subject_e config_parse_top_subject(const char *option) { if (g_strcmp0(option, SCHEMA_SUBJECT_APPS) == 0) { return TOP_SUBJECT_APPS; } else if (g_strcmp0(option, SCHEMA_SUBJECT_ALL) == 0) { return TOP_SUBJECT_ALL; } return -1; } void free_configs(config_t *configs, int len) { for (int i=0; i < len; ++i) { switch (configs[i].scope) { case PROCESS: free(configs[i].data.process.filters); break; default: break; } } }