#include "core/pch.hh" #include "core/io/config_map.hh" #include "core/config/ivalue.hh" #include "core/io/cmdline.hh" #include "core/utils/string.hh" #include "core/version.hh" void io::ConfigMap::load_cmdline(void) { for(auto it : m_values) { if(auto value = io::cmdline::get_cstr(it.first.c_str())) { it.second->set(value); } } } bool io::ConfigMap::load_file(std::string_view path) { if(auto file = PHYSFS_openRead(std::string(path).c_str())) { auto source = std::string(PHYSFS_fileLength(file), char(0x00)); PHYSFS_readBytes(file, source.data(), source.size()); PHYSFS_close(file); std::string line; std::string kv_string; std::istringstream stream(source); while(std::getline(stream, line)) { auto comment = line.find_first_of('#'); if(comment == std::string::npos) { kv_string = utils::trim_whitespace(line); } else { kv_string = utils::trim_whitespace(line.substr(0, comment)); } if(utils::is_whitespace(kv_string)) { // Ignore empty or commented out lines continue; } auto separator = kv_string.find('='); if(separator == std::string::npos) { spdlog::warn("config: {}: invalid line: {}", path, line); continue; } auto kv_name = utils::trim_whitespace(kv_string.substr(0, separator)); auto kv_value = utils::trim_whitespace(kv_string.substr(separator + 1)); auto kv_pair = m_values.find(kv_name); if(kv_pair == m_values.cend()) { spdlog::warn("config: {}: unknown key: {}", path, kv_name); continue; } kv_pair->second->set(kv_value.c_str()); } return true; } return false; } bool io::ConfigMap::save_file(std::string_view path) const { std::ostringstream stream; auto curtime = std::time(nullptr); stream << "# Voxelius " << version::semver << " configuration file" << std::endl; stream << "# Generated at: " << std::put_time(std::gmtime(&curtime), "%Y-%m-%d %H:%M:%S %z") << std::endl << std::endl; for(const auto& it : m_values) { stream << it.first << "="; stream << it.second->get(); stream << std::endl; } if(auto file = PHYSFS_openWrite(std::string(path).c_str())) { auto source = stream.str(); PHYSFS_writeBytes(file, source.data(), source.size()); PHYSFS_close(file); return true; } return false; } bool io::ConfigMap::set_value(std::string_view name, std::string_view value) { auto kv_pair = m_values.find(std::string(name)); if(kv_pair != m_values.cend()) { kv_pair->second->set(value); return true; } return false; } std::string_view io::ConfigMap::get_value(std::string_view name) const { auto kv_pair = m_values.find(std::string(name)); if(kv_pair != m_values.cend()) { return kv_pair->second->get(); } return std::string_view(); } void io::ConfigMap::add_value(std::string_view name, config::IValue& vref) { m_values.insert_or_assign(std::string(name), &vref); } const config::IValue* io::ConfigMap::find(std::string_view name) const { auto kv_pair = m_values.find(std::string(name)); if(kv_pair != m_values.cend()) { return kv_pair->second; } else { return nullptr; } }