diff options
Diffstat (limited to 'src/settings_config.c')
| -rw-r--r-- | src/settings_config.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/settings_config.c b/src/settings_config.c new file mode 100644 index 0000000..d2bc018 --- /dev/null +++ b/src/settings_config.c @@ -0,0 +1,240 @@ +/* +* BSD 2-Clause “Simplified” License +* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com +* All rights reserved. +*/ + +void settings_config_write_to_file(settings_config *config, char *path) +{ + // @hardcoded + s32 len = kilobytes(20); + char *buffer = mem_alloc(len); + buffer[0] = 0; + + for (s32 i = 0; i < config->settings.length; i++) + { + config_setting *setting = array_at(&config->settings, i); + + char entry_buf[MAX_INPUT_LENGTH]; + snprintf(entry_buf, MAX_INPUT_LENGTH, "%s = \"%s\"\n", setting->name, setting->value); + string_appendn(buffer, entry_buf, MAX_INPUT_LENGTH); + } + + set_active_directory(binary_path); + platform_write_file_content(path, "w+", buffer, strlen(buffer)); + mem_free(buffer); +} + +static void get_config_from_string(settings_config *config, char *string) +{ + config_setting current_entry; + current_entry.name = 0; + current_entry.value = 0; + + s32 len = 0; + bool in_literal = false; + char *original_string = string; + + while(*string) + { + + // property name + if (*string == ' ' && !current_entry.name) + { + current_entry.name = mem_alloc(len+1); + string_copyn(current_entry.name, string-len, len); + current_entry.name[len] = 0; + string_trim(current_entry.name); + } + + // property value + if (*string == '"' && (*(string+1) == 0 || !in_literal)) + { + in_literal = !in_literal; + + if (in_literal) + { + len = -1; + } + else + { + current_entry.value = mem_alloc(len+1); + string_copyn(current_entry.value, string-len, len); + current_entry.value[len] = 0; + string_trim(current_entry.value); + } + } + + ++len; + ++string; + } + + array_push(&config->settings, ¤t_entry); +} + +static void convert_crlf_to_lf(char *buffer) +{ + char *buffer_original = buffer; + + int write_offset = 0; + int read_offset = 0; + + while(buffer[read_offset]) + { + if (buffer[read_offset] != 0x0D) + { + buffer_original[write_offset] = buffer[read_offset]; + + ++write_offset; + } + + ++read_offset; + } +} + +settings_config settings_config_load_from_file(char *path) +{ + settings_config config; + config.settings = array_create(sizeof(config_setting)); + + set_active_directory(binary_path); + + file_content content = platform_read_file_content(path, "rb"); + + if (!content.content || content.file_error) + { + platform_destroy_file_content(&content); + return config; + } + + convert_crlf_to_lf(content.content); + + s32 token_offset = 0; + for (s32 i = 0; i < content.content_length; i++) + { + char ch = ((char*)content.content)[i]; + char prev_ch = i-1 > 0 ? ((char*)content.content)[i-1] : 255; + + // end of line [lf] + if (ch == 0x0A && prev_ch != 0x0D) + { + char line[MAX_INPUT_LENGTH]; + + s32 line_len = i - token_offset; + snprintf(line, MAX_INPUT_LENGTH, "%.*s", line_len, (char*)content.content+token_offset); + token_offset = i + 1; + + get_config_from_string(&config, line); + } + } + + platform_destroy_file_content(&content); + + return config; +} + +config_setting* settings_config_get_setting(settings_config *config, char *name) +{ + for (s32 i = 0; i < config->settings.length; i++) + { + config_setting *setting = array_at(&config->settings, i); + if (setting && setting->name && name && strcmp(setting->name, name) == 0) + { + return setting; + } + } + return 0; +} + +char* settings_config_get_string(settings_config *config, char *name) +{ + config_setting* setting = settings_config_get_setting(config, name); + if (setting) + return setting->value; + else + return 0; +} + +s64 settings_config_get_number(settings_config *config, char *name) +{ + config_setting* setting = settings_config_get_setting(config, name); + if (setting && setting->value) + return string_to_u64(setting->value); + else + return 0; +} + +void settings_config_set_string(settings_config *config, char *name, char *value) +{ + config_setting* setting = settings_config_get_setting(config, name); + if (setting) + { + s32 len = strlen(value); + mem_free(setting->value); + setting->value = mem_alloc(len+1); + string_copyn(setting->value, value, len+1); + } + else + { + config_setting new_entry; + new_entry.name = 0; + + // name + s32 len = strlen(name); + new_entry.name = mem_alloc(len+1); + string_copyn(new_entry.name, name, len+1); + + // value + len = strlen(value); + new_entry.value = mem_alloc(len+1); + string_copyn(new_entry.value, value, len+1); + + array_push(&config->settings, &new_entry); + } +} + +void settings_config_set_number(settings_config *config, char *name, s64 value) +{ + config_setting* setting = settings_config_get_setting(config, name); + if (setting) + { + char num_buf[20]; + snprintf(num_buf, 20, "%"PRId64"", value); + + s32 len = strlen(num_buf); + mem_free(setting->value); + setting->value = mem_alloc(len+1); + string_copyn(setting->value, num_buf, len+1); + } + else + { + config_setting new_entry; + + // name + s32 len = strlen(name); + new_entry.name = mem_alloc(len+1); + string_copyn(new_entry.name, name, len+1); + + // value + char num_buf[20]; + snprintf(num_buf, 20, "%"PRId64"", value); + + len = strlen(num_buf); + new_entry.value = mem_alloc(len+1); + string_copyn(new_entry.value, num_buf, len+1); + array_push(&config->settings, &new_entry); + } +} + +void settings_config_destroy(settings_config *config) +{ + for (s32 i = 0; i < config->settings.length; i++) + { + config_setting *entry = array_at(&config->settings, i); + + mem_free(entry->name); + mem_free(entry->value); + } + + array_destroy(&config->settings); +}
\ No newline at end of file |
